How to read system environment variables from repository-stored Java Specs

お困りですか?

アトラシアン コミュニティをご利用ください。

コミュニティに質問

プラットフォームについて: Server および Data Center のみ。この記事は、Server および Data Center プラットフォームのアトラシアン製品にのみ適用されます。

Support for Server* products ended on February 15th 2024. If you are running a Server product, you can visit the Atlassian Server end of support announcement to review your migration options.

*Fisheye および Crucible は除く

本記事で説明している手順は、現時点でのものとなります。そのため、一部のお客様で特定の状況下で動作したという報告がありますが、正式にサポートされているわけではなく、お客様の特定のシナリオで動作することを保証するものではありません。

本番環境での実施の前に一通り非本番環境で検証し、成功しなかった場合にはサポートされている代替案にフォール バックしてください。

また、アトラシアン サポートのサポート対象外のご質問の場合には、Community もご活用ください。

要約

Depending on your environment and scenario, you might need/want to read environment variables from your System. By default, it's not possible to do that, because, since version 6.3, Bamboo enables a Security Manager for Java Specs processing by default. It prevents the Java code from accessing the network, executing other applications, or reading/writing files. This strategy increases security since it could be very dangerous to get Java code from outside (remote repository) and execute it inside Bamboo.

環境

Using Repository-stored Bamboo Java Specs.

診断

When trying to read environment variables (example below), the Java Specs processing will fail with the following error:

Example: Java Specs code reading an environment variable
public static final String rootDomain = System.getenv("MY_VARIABLE");
Example: Java Specs error when processing the above
[ERROR] -----------------------------------------------------: access denied ("java.lang.RuntimePermission" "getenv.MY_VARIABLE")
...
Caused by: java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "getenv.MY_VARIABLE")
	at java.security.AccessControlContext.checkPermission (AccessControlContext.java:472)
	at java.security.AccessController.checkPermission (AccessController.java:886)
	at java.lang.SecurityManager.checkPermission (SecurityManager.java:549)
	at com.atlassian.bamboo.specs.maven.sandbox.AbstractThreadPermissionVerifier.checkPermission (AbstractThreadPermissionVerifier.java:18)
	at com.atlassian.bamboo.specs.maven.sandbox.BambooSpecsSecurityManager.checkPermission (BambooSpecsSecurityManager.java:37)
	at java.lang.System.getenv (System.java:894)
	at PlanSpec.<clinit> (PlanSpec.java:23)

原因


As previously mentioned, this is expected because Bamboo enables a Security Manager by default which prevents accessing and executing files.

ソリューション

Options 1-3 below only work if you are not processing Specs in Docker. If you are, please refer to the Docker section below. Additionally, please make sure that the variable you're trying to read has been picked up by Bamboo. You can check that by going to Cog icon >> Overview >> System information >> Environment Variables section. Environment variables need to be available for the user that runs Bamboo, and Bamboo needs to be restarted in order to pick up newly added variables. 

オプション 1

The best approach would be to manually modify the Java Policies used by the Security Manager to allow Bamboo to read the environment variables. This allows for more granular access control and poses fewer risks than Option 2 below.

In order to do that:

  1. Locate the .policy file under ${JAVA_HOME}/jre/lib/security/. It's usually default.policy or java.policy. Please note that this needs to be done under the Java Home directory of the JDK your Bamboo instance uses.
  2. Add the required permissions within the last grant { section:

    Policy file
    permission java.lang.RuntimePermission "getenv.MY_VARIABLE";
  3. Save the file and run the Specs Scan again. 

To know which permissions to add, please look at the error messages you get when you run the Specs Scan. You can grant access to specific variables only, or to all environment variables at once by using a wildcard: "getenv.*" (less recommended).

Option 2 (less recommended)

You can fully disable the Security Manager for Specs by adding the following property to the <bamboo-install>/bin/setenv.sh file and restarting Bamboo.

JVM_SUPPORT_RECOMMENDED_ARGS:="-Dbamboo.repository.stored.specs.security.manager.enabled=false"

Please see Configuring your system properties for detailed steps.

Disabling the Specs Security Manager brings some security risks since this way you will allow execution of any code in Specs.

オプション 3

If your scenario doesn't require the value of a variable to be available during the specs scanning process, but rather only during build time (for example, you don't have Specs conditional code that depends on a variable), the best approach would be to use Bamboo Global Variables.

You can reference Bamboo's Global Variables in your Java code directly. Let's say you have defined a Global Variable in Bamboo called "MY_VARIABLE". 

Example: Java Specs referencing a Global Variable
[...]
   .tasks(new ScriptTask()
        .inlineBody("echo ${bamboo_MY_VARIABLE}"))))
[...]

The variable's value will be used when running the build plan:

Build logs
Substituting variable: ${bamboo.MY_VARIABLE} with GLOBALVALUE

Docker

If your Bamboo is set to process Specs using Docker (cog icon >> Overview >> Security Settings >> Process Bamboo Specs in Docker), the approach will be different. You'll need to maintain your own Docker image to be used by the Docker Specs Runner, with the Java Policies already configured, since Bamboo creates a new container based on the default image every time it runs the Specs analysis. It wouldn't be possible to configure java.policy through Bamboo and use it in the Docker Specs's containers because the Docker Specs Runner runs isolated from Bamboo.

Customizing the image

You can follow the steps below to create your own customized image of the Bamboo Specs Runner:

  1. Pull Atlassian's default image from the Docker Hub repository, replacing <BAMBOO_VERSION> accordingly:

    docker pull atlassian/bamboo-specs-runner:<BAMBOO_VERSION>
  2. Run a dummy container which we'll use as the base for our new image:

    docker run atlassian/bamboo-specs-runner:<BAMBOO_VERSION>

    The container's Maven output will be an error, but that's expected since we're not actually processing any code at this moment.

  3. Get the ID of the container we've just created:

    docker ps -a
    
    CONTAINER ID   IMAGE                                        COMMAND                  CREATED         
    b76b7f9198f5   atlassian/bamboo-specs-runner:7.2.6          "/usr/local/bin/mvn-…"   3 minutes ago                         
  4. Copy the Java Policy file from the container to your local machine:

    docker cp <CONTAINER_ID>:/usr/local/openjdk-8/jre/lib/security/java.policy ~/Desktop
  5. Edit the Java Policy file according to your needs. Please see the Option 1 section above to understand what permissions to grant.

  6. Copy the updated Java Policy file back into the container:

    docker cp ~/Desktop/java.policy <CONTAINER_ID>:/usr/local/openjdk-8/jre/lib/security/
  7. Commit the container into a Docker Image:

    docker commit <CONTAINER_ID> <YOUR_REPO>/<YOUR_IMAGE>:<TAG>
  8. Push the image to your Docker repository:

    docker push <YOUR_REPO>/<YOUR_IMAGE>:<TAG>

Once you have your customized image, it's time to configure your Bamboo to use it. Please see Processing Specs in Docker with a customized image for details on how to do that.


最終更新日 2022 年 4 月 19 日

この内容はお役に立ちましたか?

はい
いいえ
この記事についてのフィードバックを送信する
Powered by Confluence and Scroll Viewport.