Skip to content

feat: live smoke gates, asgardeo experiments, and the login walkthrough - #29

Merged
kanushka merged 3 commits into
feat/login-client-credentialsfrom
feat/login-smoke-walkthrough
Aug 5, 2026
Merged

feat: live smoke gates, asgardeo experiments, and the login walkthrough#29
kanushka merged 3 commits into
feat/login-client-credentialsfrom
feat/login-smoke-walkthrough

Conversation

@kanushka

@kanushka kanushka commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Implements #23 (part of #17). Sixth and final PR of the wso2 login stack — stacked on #28; only the last three commits are new here.

What this does

  • Live smoke (//go:build smoke, make smoke-login): drives wso2 login in-process against a real issuer configured by environment variables, reads the session back from the OS secure store, then acquires through the broker. Skips cleanly naming the exact missing variables when unset. Per the design's definition of done, an auth.narrowing_unavailable refusal at acquisition is a pass once login and persistence have been proven — a correct refusal, not a fallback.
  • Empirical experiments (make empirical-asgardeo): any-port loopback redirect matching and refresh-grant scope narrowing, each printing a greppable one-line verdict. Verdict classification lives in untagged, unit-tested code — review caught that openid echoed back by a correctly-narrowing issuer would otherwise have been misclassified as "ignored" and written into the research record as a false finding about Asgardeo.
  • Walkthrough (docs/guides/login.md): Asgardeo and IS 7.x app registration with the four fixed callback URLs, a hand-authored v2 context document, first login, CI client-credentials setup, and troubleshooting for every typed refusal — self-contained by design.
  • Backend ask recorded with its owner in docs/research/product-authentication-compatibility.md §1.1 (doc imported from main, which added it after this stack was cut — expect a trivial add/add conflict on rebase; take this branch's version).
  • Smoke and empirical tests are excluded from the default go test ./... run; make smoke-build keeps the tagged code compiling.

Honest scope note

No tenant credentials exist in the implementing environment, so the research document's verdict cells read pending live run rather than fabricated results. test/smoke/RUNNING.md gives the exact commands; what remains for a human with tenant access: run make smoke-login against Asgardeo and IS 7.x, run make empirical-asgardeo and record both verdicts, and validate PR #26's nonce-echo behavior against the real deployments.

Verification

Full go test ./... -race -count=1 green (acceptance gate 166s); golangci-lint run 0 issues with and without --build-tags=smoke; the architecture-proof acceptance gate passes.

Stack

  1. feat: context schema v2 with identities, v1 compatibility read, and selection #24 schema v2 → feature/login
  2. feat: keychain session store and fake OIDC issuer test bed #25 test bed → feat/login-context-schema-v2
  3. feat: wso2 login runs browser authorization code with PKCE end to end #26 wso2 login PKCE → feat/login-auth-testbed
  4. feat: broker derives module access from the login session by scoped refresh #27 broker scoped refresh → feat/login-browser-pkce
  5. feat: acquire client-credentials access inline during the invoking command #28 inline client credentials → feat/login-broker-refresh
  6. this PRfeat/login-client-credentials

https://claude.ai/code/session_01RojiAgW9hi3b9f9G6ZXBVp

…d tag

The slice has been provable only against a fake issuer. These are the runs that
prove it against a deployment that really exists: one signs a human in through
`wso2 login`, reads the refresh token back out of the operating system's secure
store, and brokers one acquisition on top of that session; the other answers the
two questions the redirect-and-narrowing research could not settle from public
sources, and prints a verdict line for recording.

They are separated from the default gate by a build tag rather than a skip,
because scripts/acceptance.sh runs `go test ./...` and a run that opens a
browser has no place in it. A make target compiles them anyway, since the tag
that keeps them out of the gate would otherwise let them rot unnoticed.

The half that can be proven without a deployment is deliberately left untagged
and unit-tested: reading the environment that names one, building the context
document a run installs, and classifying the narrowing outcome. The last of
those matters most. Its verdict is copied by hand into a research document as a
finding about a product, so a misclassification becomes a false claim that
outlives the run — and one misclassification was real. Every login requests
openid and offline_access alongside the product permissions, so a deployment
that narrows correctly can answer with those attached and fail an exact set
comparison. Read naively that says "ignored" about a deployment that honored the
request, which is the opposite of what happened.

Nothing a run leaves behind persists. The context document goes to a temporary
state root, the session is stored under a reference no human would choose for a
real context and is deleted before and after every run, and no token is ever
printed or written.
Nothing in the tree told a person how to get `wso2 login` to work. The knowledge
existed only as the shape of a fixture and the four ports a constant names, so
the first user of a real deployment would have had to read the source to learn
what to register.

The guide is written to be read on its own, because the person who needs it has
no reason to already know which other document to open. It registers the public
client in Asgardeo and in Identity Server 7.x, authors the context document by
hand with a complete example to copy, runs the first login, and sets up a CI job
that authenticates inline with no login step at all.

Its longest section is the troubleshooting one, and that is deliberate. Every
refusal this slice can produce is typed, and a typed refusal is only as useful
as the reader's ability to turn it into something to change. Each code is listed
with what it means and what to do about it — including the five distinct
narrowing refusals, which look alike and send a reader to five different places.
…ed in

The redirect-and-narrowing research left two cells reading "unknown — needs
empirical test". The experiments that answer them now exist, but no live tenant
has been run against, so the cells say pending rather than an answer. Recording
a verdict nobody measured would be worse than leaving the question open: the
document is the thing later decisions cite, and a fabricated cell is
indistinguishable from a measured one once it is written down.

Section 4 is what makes the cells fillable — the exact commands, what each
verdict word means, and the one verdict that must be corroborated from the
browser before it is believed. It also states what each possible answer would
mean for the shell, so that the run produces a decision rather than a fact.

The compatibility document's backend gap now carries the standing ask it
implies, with its owner: a WSO2-seeded, well-known `wso2cli` public client. The
gap is stated there in the abstract; what was missing was the cost, which is
concrete and now measurable — two of the walkthrough's nine sections exist only
because every tenant registers its own client by hand.

The two documents are brought over from main, where they were written after this
branch was cut. This branch already linked to one of them, so the link was
broken until now.
@kanushka
kanushka requested a review from hevayo as a code owner August 5, 2026 04:03
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 34f65659-4f4b-4250-878a-af539689be4a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot reviewed 15 out of 15 changed files in this pull request and generated no comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants