rossoctl / rossoctl/cortex

Z5: per-subject credential resolution in static-inject (RFC 8693)

Open
#905 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

blocked enhancement Identity
Dominant language
Go
Stars
13
Forks
40
Avg merge
12h 17m
Merged PRs (30d)
156

Description

What this is

Give a tracked home to the deferred per-user half of Z5. This is not a new design: docs/specs/2026-06-19-m13-generalized-credentialed-egress-design.md already specifies generalized credentialed egress, and docs/specs/README.md:152 records that RC1 implements "a static single-tenant slice of Z5 (per-user / RFC 8693 deferred)". This issue is that deferred half.

Please read Z5 and ADR-0006 as the design; this issue records the seam and the open tension rather than restating them.

Why now

rossoctl/serverless-harness is splitting its multi-session work (issue #220 there) into three slices. Two are harness-local; the third is this one. The harness slice — rossoctl/serverless-harness#239 — makes the harness send a per-request subject and carry an inert placeholder instead of a real key. Nothing consumes that subject until static-inject can resolve a credential from it.

Until then the harness slice makes the system tenancy-neutral, not multi-tenant safe. That boundary should not be advertised as closed until this lands.

Goal

ADR-0006's (subject ⊕ destination) → credential resolution. Today static-inject resolves by destination host or a static key (ADR-0026) — one credential per deployment.

The seam

authbridge/authlib/plugins/staticinject/resolver.go:20-28 defines:

Resolve(ctx, key string) (string, bool)

implemented only by MapResolver (:28-31) and a secret_dir-style FileResolver (:39-49). Per-subject resolution makes that key subject-derived rather than destination-derived.

Prior art in this repo

authbridge/authlib/plugins/tokenbroker/plugin.go:281-294 already extracts a subject token from the inbound Authorization: Bearer header and exchanges it via client.AcquireToken. The exchange machinery exists; what is missing is static-inject keying on the result.

Design tension to settle first

The two plugins disagree about which header carries the subject:

  • P5 deliberately keeps inbound Authorization free for caller authentication, and carries the placeholder on egress Authorization: Bearer <placeholder> (the harness sets 'x-api-key': null at run-turn.ts:337), with the subject on a separate X-SH-Subject.
  • tokenbroker expects the subject token on the hop's Authorization.

Worth resolving before implementation, since it decides whether static-inject reads the subject from a dedicated header or from an exchanged token.

Note on repo naming

The harness specs and ADR-0032 still refer to this repo as kagenti-extensions, which now redirects here. Worth correcting on both sides as those docs are touched.

Blocked by

rossoctl/serverless-harness#239 — the injector cannot key on a subject the harness does not yet send.

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

Read docs/specs/2026-06-19-m13-generalized-credentialed-egress-design.md, docs/specs/README.md, and ADR-0006 first. Inspect authbridge/authlib/plugins/staticinject/resolver.go:20-49 and tokenbroker/plugin.go:281-294, then resolve the Authorization versus X-SH-Subject contract, noting the dependency on serverless-harness#239. Done means the deferred per-subject resolution seam is implemented and the tenancy boundary is no longer merely neutral.

Written by the indexing model from the issue text.

Assessment

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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.