stacklok / stacklok/toolhive

XAA/external-auth follow-ups from PR #5691 review

Open
#5,695 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Go
Stars
2.2k
Forks
300
Avg merge
1d 15h
Merged PRs (30d)
184

Description

Tracks deferred follow-up work identified during the review of #5691 (XAA auth strategy CRD support). Each item was checked against the ID-JAG draft (draft-ietf-oauth-identity-assertion-authz-grant-04) and found non-blocking for the CRD-support PR — hence this tracking issue rather than blocking that PR.

Refs #5681.


A. RFC 9470 step-up detection for XAA Step A

Context: ID-JAG draft-04 §9.2 says the IdP may return insufficient_user_authentication on the Step A token exchange when the subject's auth context is too weak, similar to RFC 9470. Today XAAStrategy propagates the raw Step A OAuth error but does not recognize this case or surface a step-up signal.

Scope: In the Step A error path (pkg/vmcp/auth/strategies/xaa.go), detect insufficient_user_authentication, log a structured WARN with acr_values/max_age, and surface ErrStepUpRequired → an RFC 9470 WWW-Authenticate challenge.

Caveats: Draft §9.2 is explicitly TBD and normatively only "may" (not a MUST) — track draft evolution before fixing a wire format (the draft's own example uses a JSON max_age body field, not an RFC 9470 header). Also entangled with the known pre-SDK-403 timing problem (token-missing is discovered inside the MCP handler, but the challenge must be emitted pre-SDK).

  • Implement insufficient_user_authentication detection + step-up surfacing (pending draft stabilization)

B. RFC 6749 §3.3 scope-grammar validation (defense-in-depth)

Context: parseXAAConfig copies cfg.Scopes verbatim into the Step A/B requests. RFC 6749 §3.3 defines the scope wire grammar (space-delimited scope-tokens, restricted charset). Malformed scopes currently reach the IdP/AS and produce an opaque invalid_scope.

Scope: Add a cheap grammar check in parseXAAConfig to reject malformed scopes before sending, per the repo's "Validate Parsed Results" rule.

Caveat: The §3.3 MUSTs bind servers (IdP/RAS), not the client — so this is defense-in-depth, not ID-JAG compliance. Low priority.

  • Add scope-grammar validation to parseXAAConfig

C. Validate MCPExternalAuthConfig secret refs at reconcile across all auth types

Context: MCPExternalAuthConfigReconciler stamps Valid=True without verifying that referenced Secrets/keys exist. A typo'd SecretKeyRef surfaces only at pod container-create (inline mode) or vMCP serve time (discovered mode). OBO already validates handler-side concerns before Valid=True (triageOBOValidation).

Scope: Add a reconcile-time step that Gets each non-nil *SecretKeyReftokenExchange.ClientSecretRef, headerInjection.ValueSecretRef, xaa.IDPClientSecretRef/TargetClientSecretRef, etc. — and sets Valid=False / Reason=InvalidConfig on miss. Do it consistently across all auth types, not XAA-only.

Caveat: Requires adding Secret get RBAC to that reconciler — an added permission surface to weigh.

  • Add cross-auth-type secret-ref existence validation at reconcile

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Review pkg/vmcp/auth/strategies/xaa.go and the parseXAAConfig path, then locate MCPExternalAuthConfigReconciler and its existing OBO validation. Decide which follow-up is ready given the draft's TBD step-up behavior and the RBAC implications. Done means the selected validation or step-up behavior is implemented consistently, with the requested error, status, logging, or challenge semantics.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
authentication, infrastructure, security
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.