Container image
With the container image delivery model, the authorization domain is built into the ADS container image instead of loaded at runtime. Each image is a versioned deployment artifact: a specific image tag corresponds to a specific policy state, which simplifies rollbacks, auditing, and promotion across environments, also in air-gapped infrastructure.
The trade-off is that every change to policies, attribute connectors, or the attribute dictionary needs a new image and a redeployment. Your CI/CD pipeline builds the image on every change, in the same way application code changes trigger an application image build. To deliver policy changes without a new image, use the Authorization Hub integration or Custom delivery.
APD stages the build context of the image. Your pipeline builds the image and pushes it to your registry, with Docker, Buildah, Kaniko, or another OCI-compatible tool.
How it works
Running the stageDeployment task assembles all artifacts needed to build a runnable ADS container image and writes them to build/install/deployment/. This directory is the build context you pass to your container build tool.
The task depends on buildAuthzDomain, so compiling policies and generating domain.yaml happens automatically.
./gradlew stageDeployment
Staged output
build/install/deployment/
├── .env.generated # Generated environment files
├── .env.generated.defaults
├── .env.generated.info
└── ads/ # Docker build context
├── Dockerfile
├── deployment.yaml # ADS deployment descriptor
├── domain.yaml # Compiled authorization domain
├── axiomatics_ADS.license
├── access-decision-service-*.jar
├── startService.sh # From src/extra, like all files there
├── logback-custom.xml
└── lib/
└── *.jar # Attribute connector JARs and your project's JAR
Pass build/install/deployment/ads/ as the build context to your container build tool.
stageDeployment does not run tests. Run the tests and stage the deployment in one command, ./gradlew test stageDeployment: Gradle runs the tests first, and stops before staging when a test fails. Otherwise, untested policies can end up in the published image.
Environment variables
ADS and attribute connectors typically reference runtime configuration, such as PIP URLs, credentials, and hostnames, as environment variables using the ${VAR} syntax. These values are environment-specific and must not be baked into the image.
As part of stageDeployment, APD scans all staged artifacts for environment variable references and generates three files at the root of the staged output, one level above the Docker build context:
.env.generated: a template listing every variable name found, with empty values. Fill in the values for your target environment before deploying..env.generated.defaults: the same variables, with their default values where they have one..env.generated.info: where each variable is referenced, its default value (if any), and commands for loading the variables on different platforms.
Example .env.generated:
# See .env.generated.info for more information
DB_PASSWORD=
LDAP_URL=
PIP_API_KEY=
The .env.generated.info file includes commands to load the .env file across different platforms. Use these as a starting point and adapt them to your needs:
# Docker
docker run --env-file .env <image>
# Kubernetes (then reference the Secret with envFrom in the pod spec)
kubectl create secret generic access-decision-service --from-env-file=.env
# Linux
export $(grep -v '^#' .env | xargs) && java -jar access-decision-service.jar
# Windows
Get-Content .env | Where-Object { $_ -notmatch '^#' -and $_ -match '=' } |
ForEach-Object { $k,$v = $_ -split '=',2; [System.Environment]::SetEnvironmentVariable($k,$v) }
java -jar access-decision-service.jar
It also contains a ready-to-use Kubernetes Secret manifest with all variables pre-populated, which you can apply directly or incorporate into your Helm chart or Kustomize overlay.
.env.generated contains empty values and is safe to commit to version control as a reference. Never commit a filled-in .env file with real secrets.
Dockerfile
The Dockerfile in your project root builds the ADS image, and stageDeployment stages it with the other files.
It adds domain.yaml last, in its own small layer. When only policies, attributes, or attribute connector configurations change and your build reuses its layer cache, the layers with ADS are reused, so the new image is quick to build, push, and pull. On build agents that start without a cache, use the cache options of your image builder, such as --cache-from and --cache-to.
ADS is installed in /opt/ads, runs as the non-root user 10001, and is started by src/extra/startService.sh. ADS listens on port 8080 (ADS_PORT). The health probes /health/startup, /health/readiness, and /health/liveness are served without authentication on the management port 8082 (ADS_MANAGEMENT_PORT). The settings of deployment.yaml are described in its comments.
If you need to customize the image (for example, to add CA certificates or change the base image), edit the Dockerfile in your project root. To customize the startup, for example to add JVM options, edit src/extra/startService.sh.
Building and pushing from a CI/CD pipeline
Use build/install/deployment/ads/ as the build context of your pipeline's container build step. See Sample CI/CD pipeline for examples for Jenkins, Azure DevOps, and GitHub Actions.