Skip to content

[Bug]: AUTHCONTEXT secret resolution undocumented -- silent Key Vault underscore failure, undocumented dash variant, silent org-level fallback trap, GitHub Environment secrets invisible at auth-check step #2153

@SteveKrisjanovsD365

Description

@SteveKrisjanovsD365

AL-Go version

v8.2

Describe the issue

There are five related problems with AUTHCONTEXT secret resolution that together create silent wrong-environment deployments with no errors and no warnings. Each problem is individually confusing; together they are a reliability and security hazard in multi-environment and multi-tenant repos. I am documenting all five here as a single issue because fixing any one of them in isolation without fixing the others would still leave users in a broken state.


Finding 1: The full lookup chain is undocumented -- the dash variant is never mentioned

Both Templates/Per Tenant Extension/.github/workflows/CICD.yaml (line 351) and Templates/Per Tenant Extension/.github/workflows/PublishToEnvironment.yaml (line 90) declare:

getSecrets: '{envName}-AuthContext,{envName}_AuthContext,AuthContext'

The PowerShell resolution logic in PublishToEnvironment.yaml lines 100-106 then evaluates them in this exact order:

"$($envName)-AuthContext", "$($envName)_AuthContext", "AuthContext" | ForEach-Object {
    if (!($authContext)) {
        if ($secrets."$_") {
            Write-Host "Using $_ secret as AuthContext"
            $authContext = $secrets."$_"
            $secretName = $_
        }
    }
}

The dash variant {envName}-AuthContext is tried first and is the highest-priority lookup. It is never mentioned anywhere in the documentation. Scenarios/secrets.md documents only <EnvironmentName>_AuthContext (underscore). A user reading the documentation has no way to know the dash variant exists, let alone that it takes precedence.

This matters practically because the dash variant is the only one of the three that works correctly with Azure Key Vault (see Finding 2 below).


Finding 2: Azure Key Vault silently skips all underscore secrets -- {env}_AuthContext silently returns null

Actions/ReadSecrets/ReadSecretsHelper.psm1 lines 158-161:

if ($secret.Contains('_')) {
    # Secret name contains a '_', which is not allowed in Key Vault secret names
    return $null
}

When Azure Key Vault is configured as the secrets provider, any requested secret name containing an underscore is immediately returned as $null. No error is thrown. No warning is written to the log. No indication is given that the lookup was skipped.

The consequence: the documented pattern <EnvironmentName>_AuthContext is silently non-functional when Azure Key Vault is in use. A user who reads Scenarios/secrets.md, creates a Key Vault secret named MY-UAT_AuthContext, and triggers a deployment to MY-UAT will get no error. The workflow log will not mention that the Key Vault lookup was skipped. The workflow silently falls through to the generic AuthContext fallback.

The dash variant {env}-AuthContext does work with Key Vault because dashes are permitted in Key Vault secret names. This is never documented.


Finding 3: The generic AuthContext fallback is a silent cross-environment credential trap

When neither {env}-AuthContext nor {env}_AuthContext resolves to a value, AL-Go silently falls back to the generic AuthContext secret. The only log evidence of this is the message Using AuthContext secret as AuthContext. There is no warning that this is a fallback, no indication that a per-environment secret was expected but not found, and no indication that the credentials being used may not correspond to the target environment.

In organizations that define AUTHCONTEXT at the org level and share it with all repositories (a common pattern for product repos), every environment in every repo that lacks a per-environment secret will silently deploy using the org-level credential.

In a multi-tenant PTE scenario this creates a security isolation failure:

  • A TenantApps repo has environments CUSTOMER-A-UAT and CUSTOMER-B-UAT
  • Neither has a per-environment AuthContext secret defined
  • The org-level AUTHCONTEXT belongs to Customer A's BC service account
  • A developer triggers Publish To Environment targeting CUSTOMER-B-UAT
  • AL-Go resolves to the org-level AUTHCONTEXT (Customer A's credentials) with no warning
  • The workflow reports success; the log says "Using AuthContext secret as AuthContext"
  • No error is thrown and no credential mismatch is flagged

In regulated industries where BC tenant isolation is a compliance requirement, this silent fallback is particularly dangerous.


Finding 4: GitHub Environment secrets are invisible at the auth-check initialization step

In both CICD.yaml and PublishToEnvironment.yaml, the Read secrets step that performs AUTHCONTEXT resolution runs inside the Initialization job, which has no environment: property set. GitHub Actions injects environment-scoped secrets only into jobs that explicitly declare environment:. The downstream deploy matrix jobs do have environment: set and receive GitHub Environment secrets correctly -- but that is too late for the auth-check logic.

Scenarios/RegisterSandboxEnvironment.md guides users through creating GitHub Environments and setting AUTHCONTEXT under them as environment secrets. A user following this documentation exactly will find that the auth-check step in PublishToEnvironment.yaml lines 77-122 cannot see their secret. For an unknown or newly-registered environment the workflow enters device-flow or falls back to the generic AuthContext. The user's correctly-configured environment-scoped secret is silently ignored.

The documentation does not clarify which job context has access to GitHub Environment secrets, nor does it warn that environment-scoped AUTHCONTEXT secrets are not effective at the initialization auth-check step.


Finding 5: Users are forced into undocumented workarounds

Because of findings 2-4, teams managing multiple customer repos with isolated BC environments cannot safely rely on any of the documented mechanisms:

  • {env}_AuthContext at repo or org level -- silently broken with Key Vault (Finding 2)
  • GitHub Environment AUTHCONTEXT -- invisible to the auth-check step (Finding 4)
  • Org-level AUTHCONTEXT -- silently deploys using wrong credentials when per-environment secrets are absent (Finding 3)

Teams running into these failure modes are forced to develop their own workarounds and naming conventions with no documentation to guide them. The fact that there is no documented recommended pattern for multi-tenant or multi-environment isolation means every team rediscovers these problems independently.


Expected behavior

  1. Scenarios/secrets.md should document all three lookup variants -- {envName}-AuthContext, {envName}_AuthContext, and AuthContext -- in explicit precedence order, with a clear explanation of why each exists and when each is appropriate.

  2. The Key Vault + underscore silent skip should be called out explicitly: "If using Azure Key Vault as your secrets provider, secret names containing underscores are silently skipped due to a Key Vault naming restriction. Use the dash variant {envName}-AuthContext when storing per-environment secrets in Key Vault."

  3. The generic AuthContext fallback should be documented with a clear warning: "If no per-environment secret is found, AL-Go falls back to the generic AuthContext secret without warning. In multi-environment or multi-tenant repos this can result in the wrong credentials being used. Ensure all environments have per-environment secrets if credential isolation is required."

  4. Scenarios/RegisterSandboxEnvironment.md and Scenarios/RegisterProductionEnvironment.md should clarify that GitHub Environment secrets are only available to jobs that declare environment:. The AUTHCONTEXT resolution in the Initialization job does not have this context. Environment-scoped AUTHCONTEXT secrets must be at repo or org level to be found during initialization.

  5. In ReadSecretsHelper.psm1, rather than silently returning $null when a secret name contains an underscore, emit a Write-Host warning so that the workflow log records that the lookup was skipped and why.

  6. A documented recommended pattern for multi-tenant and multi-environment isolation should be added.

Steps to reproduce

Key Vault + underscore silent failure (Finding 2)

  1. Create an AL-Go PTE repo from the standard template.
  2. Register a GitHub environment named MY-UAT.
  3. Configure Azure Key Vault integration by adding the AZURE_CREDENTIALS secret.
  4. In Azure Key Vault, create a secret named MY-UAT_AuthContext containing valid BC AuthContext JSON.
  5. Trigger Publish To Environment targeting MY-UAT.
  6. Observe: the workflow does not use the Key Vault secret. It falls back to a generic AuthContext or initiates device flow. No log line indicates the Key Vault lookup was skipped.
  7. Reference: Actions/ReadSecrets/ReadSecretsHelper.psm1 line 158 -- the Contains('_') check causes immediate return $null with no log output.

Silent cross-environment credential fallback (Finding 3)

  1. At the GitHub organization level, define an AUTHCONTEXT secret for Customer A's BC service account. Share it with all repositories.
  2. Create a TenantApps repo with two AL-Go environments: CUSTOMER-A-UAT and CUSTOMER-B-UAT. Do not create any per-environment AuthContext secrets.
  3. Trigger Publish To Environment targeting CUSTOMER-B-UAT.
  4. Observe: the log says Using AuthContext secret as AuthContext. The org-level credential (Customer A's) is used to publish to Customer B's environment. No warning is emitted. The workflow reports success.

GitHub Environment secret invisible to auth-check (Finding 4)

  1. Follow Scenarios/RegisterSandboxEnvironment.md exactly: create a GitHub Environment named MY-SANDBOX, add AUTHCONTEXT as an environment secret under it (not as a repo or org secret).
  2. Trigger Publish To Environment targeting MY-SANDBOX.
  3. Observe: the Initialization job does not find AUTHCONTEXT. The workflow initiates device flow or falls back to a repo/org-level secret. The GitHub Environment secret is never visible to the initialization auth-check step.

Additional context

These issues were identified during a pilot of AL-Go for agentic DevOps workflows across multiple TenantApps repos serving distinct customers with isolated BC tenants. The silent fallback behavior in Finding 3 is particularly concerning: a misconfigured deployment that silently uses the wrong service account credentials is indistinguishable from a correct one in the workflow log.

The combination of Finding 1 and Finding 2 is especially problematic: a user following the published documentation who is also using Azure Key Vault is in a completely broken state with no diagnostic path. They are not told about the dash variant, so they use the documented underscore variant. The underscore variant returns null silently. The fallback activates silently. The workflow shows a green checkmark. The user has no idea their Key Vault secret was never consulted.

Relevant source file references:

  • Templates/Per Tenant Extension/.github/workflows/CICD.yaml, line 351 -- getSecrets declaration
  • Templates/Per Tenant Extension/.github/workflows/PublishToEnvironment.yaml, line 90 -- getSecrets declaration
  • Templates/Per Tenant Extension/.github/workflows/PublishToEnvironment.yaml, lines 100-106 -- resolution loop
  • Actions/ReadSecrets/ReadSecretsHelper.psm1, lines 158-161 -- underscore null return with no log output
  • Scenarios/secrets.md -- documents only underscore variant; dash variant absent; no Key Vault compatibility notes; fallback behavior not warned against
  • Scenarios/RegisterSandboxEnvironment.md -- does not clarify initialization job vs deploy job secret scope

Metadata

Metadata

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions