registrystack / registrystack/registry-stack

Token path diagnostics: BREG, the Casework BREG adapter and bregctl dev drop the refusal cause

Open
#1,076 0 comments 0 reactions 0 assignees View on GitHub
area:breg area:casework criticality:p3 enhancement
Dominant language
Rust
Stars
2
Forks
0
Avg merge
2h 57m
Merged PRs (30d)
128

Description

## Use Case

An adopter wires Casework to BREG with a new issuer or client configuration and something in the token path is wrong: a missing claim, a wrong assertion audience, an issuer response the client refuses.

## What we hit

Each layer keeps the cause to itself, so the only way to find it was reading source or adding instrumentation:

- **BREG**: `authenticate_request` in `crates/registry-breg/src/auth.rs` discards the `AuthenticationError` and answers `authentication.refused`. Nothing is logged server side for `InvalidClaims` (for example a service token without `registry_actor_kind`); only an unknown `kid` warns. The operator cannot tell a bad signature from a missing claim.
- **Casework BREG adapter**: `read_error` in `crates/registry-casework-breg/src/lib.rs` maps by HTTP status only. A token acquisition failure has no status and becomes `Unavailable`; a BREG `401` on a readback becomes `Concealed`. The reconciliation loop in `crates/registry-casework/src/runtime.rs` then logs only `Casework reconciliation pass did not complete` with that adapter error, so "the issuer refused our client assertion" and "BREG is down" look identical.
- **`bregctl dev`**: `probe` in `crates/registry-bregctl/src/dev/mod.rs` reports `a requested local port is already occupied; stop its owner or choose other ports` without naming the port, while a start binds three.

## Proposed Behavior

- BREG logs the refusal reason category (malformed credential, signature, issuer, audience, expiry, missing or invalid claim name) at `warn` or `info`, rate limited, without token contents. The HTTP answer stays `authentication.refused`.
- The Casework adapter keeps the underlying cause (token error kind, BREG problem code, status) in the error it returns, and the reconciliation warning prints it. `Concealed` stays what callers see; the operator log says what happened.
- `bregctl dev` names the occupied port and which role (BREG, issuer, database, receiver) asked for it.

## Boundaries

- No token, assertion, key or claim value in logs; claim names only.
- Caller-facing problem codes and concealment do not change.

Related: #1005, #1006.

Contributor guide

Open the contributing guide

Research direction

Start with authenticate_request in crates/registry-breg/src/auth.rs, read_error in crates/registry-casework-breg/src/lib.rs, the reconciliation logging in crates/registry-casework/src/runtime.rs, and probe in crates/registry-bregctl/src/dev/mod.rs. Trace the existing error paths before changing them. Done means refusal categories, adapter causes, reconciliation warnings, and occupied port roles are visible without exposing token contents or changing caller-facing codes.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
authentication, backend-api-design, cli, observability
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.