Repository navigation
test(e2e): sign in through hosted AS-1 with Dex, plus a local Kind profile - #2622
Merged
Merged
Conversation
ChrisJBurns
force-pushed
the
test/identitybroker-as1-kind-e2e
branch
from
October 30, 2026 13:31
06a683d to
503165f
Compare
ChrisJBurns
force-pushed
the
feat/identitybroker-host-as1
branch
from
October 30, 2026 13:39
99fe64e to
65a2a75
Compare
ChrisJBurns
force-pushed
the
test/identitybroker-as1-kind-e2e
branch
from
October 30, 2026 13:40
503165f to
e04ca1d
Compare
ChrisJBurns
force-pushed
the
test/identitybroker-as1-kind-e2e
branch
from
October 30, 2026 14:14
e04ca1d to
39f3cdc
Compare
ChrisJBurns
added a commit
that referenced
this pull request
Oct 30, 2026
… admission Review follow-ups for #2622: - k8s-e2e path filter: internal/adapter/server/**, authn/oidc/**, and mcp/oauthlogin/**, so changes to code the spec exercises run the suite. - --identity-broker-as1-upstream-allow-private-addresses now requires --identity-broker-as1-upstream-ca-file, like --oidc-allow-private-https-issuer requires --oidc-ca-cert-file; the chart refuses the same. Help and docs say it applies to every request AS-1 makes to the upstream IdP, including discovered endpoints and redirects. - Kind spec: bob, signed in through AS-1 and Dex, does not see alice's session and gets 404 opening it; AS-1-signed tokens with the wrong audience or without sub_id get 401, with a correctly minted control token accepted; the restart spec names #2563. - Smaller fixes: Dex pod without a service-account token, a helm-unittest case for a CA key without a Secret, a profile-specific /etc/hosts backup in hosts-remove, and a comment naming ToolHive's consent template. Refs #2621 Co-authored-by: Mecatl <noreply@mecatl.dev>
Adds a Kind e2e spec that deploys a second, single-replica mecak8s release with the identity broker and AS-1 on, TLS, and an HTTPS Dex as AS-1's upstream, all in their own namespace. The real mecatui login signs in through AS-1 and Dex; the spec checks the protected-resource metadata, the at+jwt token and its sub_id, sub_id session ownership, refresh rotation, and that after a pod restart a pre-restart access token still passes while AS-1's earlier refresh token is refused. Also adds --identity-broker-as1-upstream-ca-file and --identity-broker-as1-upstream-allow-private-addresses, with Helm values, so AS-1 can use an IdP behind a private CA or on a private address, and extends the k8s-e2e path filter to the identity broker code. Closes #2621 Co-authored-by: Mecatl <noreply@mecatl.dev>
task mecak8s-idbroker:kind-setup creates a separate mecatl-idbroker Kind cluster (host ports 18090, 18091, 5557, so it runs alongside mecatl-dev), builds and loads the mecak8s image, installs cert-manager and a fixture CA, deploys Dex over HTTPS with two dev-only users, and installs mecak8s with the identity broker and hosted AS-1 using Dex as its upstream. hosts-add, login, connect, image-refresh, status, and destroy cover the rest of the loop. A fixture test keeps ports, host names, the Dex client redirect, the audience URL, and the login and connect tasks consistent. Refs #2621 Co-authored-by: Mecatl <noreply@mecatl.dev>
… profile Co-authored-by: Mecatl <noreply@mecatl.dev>
AS-1 (ToolHive) accepts only an absolute http or https URI with a host and no fragment as an allowed audience and fails at startup otherwise. mecak8s and the chart now refuse any other --oidc-audience when --identity-broker-as1-issuer is set, and the production identity-broker CI fixture uses a URL audience. Refs #2490 Co-authored-by: Mecatl <noreply@mecatl.dev>
… admission Review follow-ups for #2622: - k8s-e2e path filter: internal/adapter/server/**, authn/oidc/**, and mcp/oauthlogin/**, so changes to code the spec exercises run the suite. - --identity-broker-as1-upstream-allow-private-addresses now requires --identity-broker-as1-upstream-ca-file, like --oidc-allow-private-https-issuer requires --oidc-ca-cert-file; the chart refuses the same. Help and docs say it applies to every request AS-1 makes to the upstream IdP, including discovered endpoints and redirects. - Kind spec: bob, signed in through AS-1 and Dex, does not see alice's session and gets 404 opening it; AS-1-signed tokens with the wrong audience or without sub_id get 401, with a correctly minted control token accepted; the restart spec names #2563. - Smaller fixes: Dex pod without a service-account token, a helm-unittest case for a CA key without a Secret, a profile-specific /etc/hosts backup in hosts-remove, and a comment naming ToolHive's consent template. Refs #2621 Co-authored-by: Mecatl <noreply@mecatl.dev>
ChrisJBurns
force-pushed
the
test/identitybroker-as1-kind-e2e
branch
from
November 1, 2026 17:59
8b73419 to
2903e19
Compare
jhrozek
approved these changes
Nov 1, 2026
This was referenced Nov 2, 2026
This branch was successfully deployed
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.
Follows #2613 (merged). Closes #2621.
Summary
--identity-broker-as1-upstream-ca-file(a PEM CA bundle trusted in addition to system roots) and--identity-broker-as1-upstream-allow-private-addresses, both refused without--identity-broker-as1-issuer. Admitting private addresses requires the CA file, as--oidc-allow-private-https-issuerrequires--oidc-ca-cert-file. It applies to every request AS-1 makes to the upstream IdP (discovery, discovered endpoints, redirects), because ToolHive enforces it in its HTTP client's dialer; the flag help and values say so. Helm:identityBroker.as1.upstream.caSecret.{secretName,key}(mounted read-only) andidentityBroker.as1.upstream.allowPrivateAddresses. Moved here from Operator configuration, keys, and deployment #2538; the kind/Keycloak demo uses them too.httporhttpsURL with a host and no fragment as its audience and otherwise fails at startup. mecak8s now refuses any other--oidc-audiencewhen--identity-broker-as1-issueris set, the chart refuses it at render time, and the production identity-broker CI fixture useshttps://mecatl.example.com/apiinstead ofmecatl.e2e/k8s/hosted_as1_test.go, build tagkind_e2e): in its own namespacemecatl-as1, so the suite's two-replica release and existing Dex are untouched:v2.44.0(the suite's image) on HTTPS with alice and bob and a static client for AS-1, without a service-account token;--no-shell, OIDCsub_idownership, the broker, AS-1 athttps://mecak8s-as1.mecatl-as1.svc.cluster.local:8081/as1, a signing-key Secret, and the new CA and private-address values;clientauth.Loginfrom the test process, through port-forwards (the client maps in-cluster host names to them; no/etc/hosts), with a browser that fills Dex's login form and approves AS-1's consent page (detection follows ToolHive'sconsentPageTemplate).deploy/mecak8s-idbroker/, root includemecak8s-idbroker:):task mecak8s-idbroker:kind-setupcreates a separatemecatl-idbrokerKind cluster (host ports 18090, 18091, 5557, so it runs alongsidemecatl-dev), builds and loads the image, installs cert-manager and a fixture CA, deploys Dex over HTTPS with a dev-only userdev@example.com, and installs mecak8s with the broker and AS-1 (values-kind-idbroker.yaml). Thenhosts-add,login,connect; alsoimage-refresh,status,hosts-remove(with its own/etc/hostsbackup), anddestroy. A fixture test keeps ports, host names, the Dex redirect, the audience URL, and the login and connect tasks consistent. Verified live: full sign-in through AS-1 and Dex, sessions over HTTPS and gRPC, per-user isolation,image-refreshkeeping the signing key, anddestroyremoving only its own cluster. Added to Test hosted AS-1 in the Kind e2e suite with Dex, and add a local Kind profile #2621's scope.k8s-e2e.ymlpath filters addinternal/identitybroker/**,internal/app/identitybroker.go,internal/adapter/clientauth/**,internal/adapter/server/**(replacing the individual files),authn/oidc/**, andmcp/oauthlogin/**.What the spec asserts
typ: at+jwt, AS-1'siss,client_id,aud, and asub_id(iss_sub) naming Dex's issuer and subject.sub_id; his session list leaves out alice's session, opening hers returns 404, and alice still sees hers but not his.sub_id, get 401; a control token minted the same way with the correct claims is accepted, so the refusals come from the claim checks.sub_id, rotates the refresh token, and opens a session.invalid_grant(AS-1's in-memory state until Durable broker state and recovery #2563, which flips this assertion).Observed Dex behaviour: AS-1's consent page comes first, then Dex's login form; Dex v2.44 shows no approval screen for
prompt=consentwithskipApprovalScreen(the browser approves one if a later Dex shows it). The spec shows that AS-1 requestsoffline_accesswithprompt=consent; that Dex issued an upstream refresh token is not asserted (that would need Dex's gRPC API).Testing
GOWORK=off go test -tags kind_e2e -count=1 -timeout 40m ./e2e/k8s/ -ginkgo.focus='hosted AS-1'passes 7/7 (85 s).go test ./cmd/mecak8s/... ./deploy/helm/mecak8s/ ./deploy/mecak8s-idbroker/, helm-unittest, kubeconform,docs:check, andsite:buildpass; lint clean on touched packages.API compatibility
--identity-broker-as1-issuer; no wire change. With AS-1 enabled, a non-URL--oidc-audience(oidc.audience) is now refused at flag parsing and at chart render time; this moves an existing AS-1 startup failure earlier with a clear message.