Realizes COMMONS-9–COMMONS-12. See T-LEAK.
The error model splits cleanly by layer: libraries throw typed exceptions; HTTP edges
render RFC 9457 problem documents. Commons owns the typed hierarchy (commons.error) and
the inbound normalization of IdP error responses; each edge owns its RFC 9457 mapping.
| Layer | Behaviour |
|---|---|
Libraries — |
Throw a typed exception hierarchy defined in |
HTTP edges — |
MUST map those exceptions to |
A small, stable hierarchy that library code throws and edges map:
-
TokenSheriffExceptionis the common base, carrying a category (fromcommons.events, structure / signature / semantic) and a safe, caller-facing message — never internal detail. -
Transport failures (TLS rejected, SSRF blocked, timeout, oversized response, unreachable endpoint) are the
TransportExceptionbranch; inbound IdP protocol errors normalize toClientProtocolException(viaInboundErrorNormalizer). -
Token-validation failures (
TokenValidationException, keyed bySecurityEventCounter.EventType) are another branch on the shared base so the edges have one mapping surface.
Each edge maps the typed exception to a problem document:
| Category | HTTP status | type / title |
|---|---|---|
Transport (SSRF blocked, TLS rejected, unreachable, timeout) |
502 / 503 as appropriate |
Stable |
Structure / signature / semantic (token rejection) |
401 |
Stable |
Bad request (malformed input) |
400 |
Stable |
A problem document carries type, title, status, and a safe detail. It MUST NOT
carry stack traces, internal identifiers, upstream URLs, or credential material
(COMMONS-12, mitigating T-LEAK).
Because every rendered member is a fixed, per-category constant (no request or exception
data is interpolated), the validation-quarkus edge builds the document from constant
strings — guaranteeing the exact application/problem+json bytes with no escaping surface.
If a future edge needs a dynamic detail (interpolating request-derived text), it MUST
switch to a serialized DTO with proper JSON escaping rather than string concatenation.
{
"type": "https://cuioss.github.io/TokenSheriff/problems/token-invalid",
"title": "Token validation failed",
"status": 401,
"detail": "The presented token could not be validated."
}Commons normalizes inbound OAuth error responses (error / error_description, RFC 6749
§5.2) into the same typed model the edges render — one contract, both directions. The
raw upstream error is never passed through to the caller verbatim.
-
Observability specification —
SecurityEventCounter/ categories