feat: Microsoft Entra authentication for Temporal (server JWT + UI OIDC)#89
Merged
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Replaces the unused UISpec.Auth passthrough with a typed UIAuthSpec. BREAKING CHANGE: spec.ui.auth is now a typed object, not raw YAML. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Split 03-authz-checks.yaml into two sequential phases: - 03-authz-allow.yaml: ConfigMap (valid + invalid tokens) + authz-allow Job - 04-authz-deny.yaml: authz-deny Job + new authz-bad-token Job chainsaw-test.yaml gains two steps (authz-allow, authz-deny) replacing the single authz-checks step. The denial step is only reached after authz-allow succeeds, proving the JWKS endpoint was fetched and the validator is live — closing the fail-open race window. authz-bad-token exercises token-invalid.txt (valid structure, wrong signature) in-cluster, proving signature verification and not just missing-auth rejection. backoffLimit:0 on both denial Jobs prevents retries masking false positives. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Change AuthorizationSpec.Authorizer from string to *string so an explicit empty value is distinguishable from unset. Add EmitAuthorizer bool to AuthConfig and update buildAuth to default to "default" only when the field is nil (unset). Update the config template to gate authorizer emission on EmitAuthorizer rather than a non-empty string check, so authorizer: "" renders correctly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Update CRD description, API reference docs, and Helm chart CRD to reflect the new Authorizer *string doc comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
…ons, passthrough) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Signed-off-by: Brian Morton <brian@mmmhm.com>
bmorton
force-pushed
the
feat/entra-authentication
branch
from
June 24, 2026 19:09
db987af to
918c372
Compare
bmorton
added a commit
that referenced
this pull request
Jun 25, 2026
The Microsoft Entra fields added in #89 committed a dist/chart CRD whose descriptions were wrapped by a different generation process. The pinned 'make helm-chart' (kubebuilder helm/v2-alpha) emits single-line descriptions, so the verify-chart CI check added in #98 flagged the artifact as stale. Regenerate dist/chart deterministically; the change is purely description re-wrapping with no semantic difference. Signed-off-by: Brian Morton <brian@mmmhm.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires Microsoft Entra into Temporal for both service-to-service JWT auth and
human UI login, building on the passwordless Entra work from #85. Stock
temporalio/serverandtemporalio/uiimages throughout — no custom claimmapper or image.
What's included
Server JWT auth (
spec.authorization)entra.tenantIDshortcut that derives the Entra JWKS URL(
https://login.microsoftonline.com/<tenant>/discovery/v2.0/keys), plusexplicit
jwtKeyProvider.keySourceURIs/refreshIntervalandpermissionsClaimName(defaults toroleswhenentrais set — Entra approles land in the
rolesclaim).authorizeris now a*string: unset → defaults to"default"(per-namespace RBAC) when JWT is configured;
""→ Temporal's no-opauthorizer for authenticate-only mode. Both modes are first-class.
authorization.configpassthrough is now rendered (andcleanly overrides modeled keys, incl.
jwtKeyProvider, with no duplicate YAML).UI OIDC login (
spec.ui.auth)ui.authraw passthrough with a typedUIAuthSpec:enabled,entra.tenantID,providerURL,clientID,clientSecretRef,scopes,callbackURL,extraEnv— rendered asTEMPORAL_AUTH_*env on theUI Deployment. The client secret is sourced via
secretKeyRefand neverinlined.
Validation, docs, example, tests
ui.auth(required fields; exactly one provider source;extraEnvmust be a string map).docs/content/operations/authentication.md(authn-only + RBAC viaEntra app roles, UI OIDC, the longstanding app, security caveats),
cross-linked from the Azure install guide. Regenerated CRD/API reference,
mirrored into
dist/chart.examples/cluster-entra-auth/using a 1PasswordOnePasswordItemforthe UI client secret.
test/e2e/entra-auth/, Chainsaw on kind, noAzure): an offline RSA keypair + static JWKS, baked valid/invalid JWTs, proves
a valid
<namespace>:<role>token is authorized and missing/wrong-signaturetokens are rejected — with the denial checks gated on the validator being
demonstrably live.
hack/entra-e2e.sh(+make entra-e2e-up/-token/-down) creates a longstandingEntra app registration (app roles
default:read/default:write/temporal-system:admin) for manual real-Entra verification.Breaking change
spec.ui.authchanges from raw YAML to a typed object. The field was previouslydead (never rendered), and the project is pre-1.0.
Validation
make build,make test,make lint(0 issues), andmake generate manifests(no drift) all pass. The hermetic e2e suite's crypto is verified offline; the
live kind run is documented (not run in this environment).
Design + plan:
docs/superpowers/specs/2026-06-21-entra-authentication-design.md,docs/superpowers/plans/2026-06-21-entra-authentication.md.