Inspect a running service's env & secrets
There is no per-service .env in the cloud. Deployed
Configuration lives as GitHub org-level Variables and Secrets, and the deploy engine
selects them by prefix and injects them into the Azure Container App — see
Environment & service-discovery. The catch: the
deploy job declares no GitHub environment: block, so those org-level values are
invisible to an ordinary read:org token — you can’t list them from GitHub. The only
reliable source of truth for what a service actually received is the live container.
This page is the runbook for reading it with az, and the one rule that keeps it safe:
the env dump shows secret references, never secret values.
Before you start
Section titled “Before you start”- Azure CLI logged in to the subscription that owns
rg-core(az login, thenaz account setif you belong to several). Reading a container app needs Reader on the resource group. - The
containerappextension:az extension add --name containerapp(oraz extension update --name containerapp). - The app name. Every app is
<service>-<env>— e.g.core-gateway-consumer-staging,core-database-prod. Workers follow the same pattern (core-tool-agent-staging), they just have no ingress. The full list lives in the Service catalog.
Read the effective environment
Section titled “Read the effective environment”-
Dump the container’s env array. Every app is in resource group
rg-core:read one service's effective env az containerapp show \-n core-gateway-consumer-staging \-g rg-core \--query "properties.template.containers[0].env" -
Read the two shapes. Each entry is either a plain Variable or a secret reference:
properties.template.containers[0].env (illustrative — values elided) [{ "name": "ENVIRONMENT", "value": "staging" },{ "name": "CORE_DATABASE_GRPC", "value": "<fqdn>:443" },{ "name": "REDIS_ADDR", "value": "<redis-url>" },{ "name": "INTERNAL_RPC_SECRET", "secretRef": "internal-rpc-secret" },{ "name": "REDIS_PASSWORD", "secretRef": "redis-password" }]A
valuefield is an org Variable, injected inline. AsecretReffield is an org Secret — the container spec holds only the reference name, never the value. -
Narrow to what you need. JMESPath projections keep the output tight and keep values off your screen entirely:
just the names — no values at all az containerapp show -n core-gateway-consumer-staging -g rg-core \--query "properties.template.containers[0].env[].name" -o tsvis one var wired, and how? az containerapp show -n core-gateway-consumer-staging -g rg-core \--query "properties.template.containers[0].env[?name=='INTERNAL_RPC_SECRET']"
Map a name back to its source
Section titled “Map a name back to its source”The names you see are the deploy-injection convention in reverse:
| In the container | Injected from (org-level, STAGING_/PROD_) |
Kind |
|---|---|---|
INTERNAL_RPC_SECRET → secretRef internal-rpc-secret |
STAGING_INTERNAL_RPC_SECRET (Secret) |
Secret |
REDIS_ADDR = value |
STAGING_REDIS_ADDR (Variable) |
Variable |
CORE_DATABASE_GRPC = <fqdn>:443 |
STAGING_CORE_DATABASE_GRPC (auto-published on deploy) |
Variable |
The rule: the env-var name is the org name with the STAGING_/PROD_ prefix stripped;
a secret’s secretRef is that stripped name lower-cased with _ → - — so
STAGING_INTERNAL_RPC_SECRET becomes env INTERNAL_RPC_SECRET pointing at ACA secret
internal-rpc-secret. Service-to-service URLs (CORE_*_GRPC) are the previous deploy’s
published FQDN, not something you set by hand.
The ACA secrets themselves
Section titled “The ACA secrets themselves”A secretRef points at a named ACA secret. You can list which secret names are wired on an
app — but never print their values:
az containerapp secret list -n core-gateway-consumer-staging -g rg-core \ --query "[].name" -o tsvOther useful reads
Section titled “Other useful reads”All are az containerapp show -n <app> -g rg-core unless noted:
| Question | --query |
|---|---|
| Which image/tag is live? | "properties.template.containers[0].image" |
| What is the public FQDN? | "properties.configuration.ingress.fqdn" |
| Is ingress external? | "properties.configuration.ingress.external" |
| Which revisions exist? | az containerapp revision list -n <app> -g rg-core -o table |
The image tag is the commit SHA the deploy built from — the fastest way to answer “is my fix actually live?” before you dig further. Revisions feed the rollback runbook.
When a name is simply missing
Section titled “When a name is simply missing”If a name your code reads is absent from the env array, the service didn’t error — it
silently fell back to a hard-coded default. That is the class of bug behind historical
INTERNAL_AUTH_SECRET vs INTERNAL_RPC_SECRET and REDIS_URL vs REDIS_ADDR drifts: the org
published one name, the code read another, and nothing complained. When a service “can’t find”
a dependency, diff the names it reads against this env dump first. See
Troubleshooting.
Related
Section titled “Related”- Environment & service-discovery convention — the prefix-strip injection and
*_GRPCFQDN publishing this page reads back - CI/CD deploy pipeline — where these env vars get set on the app
- Environment variable catalog — canonical fleet names and what each points at
- Roll back a deployment — revisions and traffic pinning
- Troubleshooting FAQ — silent name-mismatch fallbacks