---
id: w4/m9/t005
title: E2E verify (DCR → PKCE → dashboard login → consent → Bearer → /mcp) + docs
worker: worker4
status: done
estimate: 60m
depends_on: [w4/m9/t002, w4/m9/t003, w4/m9/t004]
---

## Objective

Prove the whole story end-to-end as a Claude-Code-shaped client would live it,
locally and scripted: discover the AS from bex-api's resource metadata →
DCR-register → auth-code + PKCE → the **existing dashboard login page** (Kratos
session; Kratos accepts the challenge natively) → headless consent → token →
`Authorization: Bearer` call to bex-api `/mcp`. Then rewrite `docs/ADR012-auth.md` §7
to record the corrected architecture.

## Context

- Script home: `scripts/` (sibling of `auth-e2e.sh` / `auth-verify.sh`, reusing
  their port-forward patterns for hydra/kratos/bex-api on the mock cluster).
- The mark-trusted step for the test client (so t003 auto-consents) is part of
  the script (Hydra admin `skip_consent` flag on the DCR-created client — an
  operator action, mirroring how a real trusted agent would be blessed).
- Docs: `docs/ADR012-auth.md` gains/rewrites the OAuth-provider section — first-party
  = Kratos sessions (unchanged), third-party agents = OAuth 2.1 via the native
  bridge; include the local run steps and the DO_NOT_DO guardrails.

## Steps

1. Write `scripts/auth-oauth21-e2e.sh`: metadata discovery → DCR → bless client → PKCE authorize (drive login via Kratos native flow or a real browser step) → consent → token → Bearer `/mcp` call asserts 2xx.
2. Run it against the local mock cluster; fix whatever it flushes out.
3. Rewrite `docs/ADR012-auth.md` §7 (+ prettier).

## Files

- `scripts/auth-oauth21-e2e.sh` (new)
- `docs/ADR012-auth.md`

## Acceptance criteria

- [x] The script passes end-to-end on the local mock cluster.
- [x] The dashboard's own login (no challenge) is demonstrably unchanged (existing dashboard tests green).
- [x] `docs/ADR012-auth.md` documents the architecture + local run; markdown prettier-clean.

## Out of scope

- Prod rollout verification (config ships via the same GitOps values; verify on next deploy).
