Skip to content

Repository files navigation

auth9token-go

Go verifier for auth9-issued access tokens.

  • RS256/ES256 signature verification against the issuer's JWKS (HS*/none always rejected — no algorithm-confusion surface).
  • Pinned issuer and audience, required exp, nbf handling, 30s default clock-skew leeway.
  • Production JWKS cache: positive/negative TTLs, refresh floor, singleflight stampede control, redirect refusal, response-size cap, RSA/EC key sanity bounds. HTTPS required (plain HTTP only on loopback, opt-in).
  • Typed failure reasons: expired, not_yet_valid, audience_mismatch, issuer_mismatch, bad_signature, unknown_key, internal — every path fails closed.
  • Claim-provenance readers: distinguish issuer-attested top-level claims from caller-asserted passthrough under the reserved caller container (see ProvenanceClaims).
  • Ships the issuer-generated conformance corpus (conformance/fixtures.json) and replays every vector through this verifier in its own test suite.

This library answers exactly one question: was this token minted by your auth9 issuer, for your audience, and is it currently valid? Authorization — scopes, roles, tenancy rules, admission policy — deliberately does not live here; keep it in your service.

Install

go get github.com/db9-ai/auth9token-go

Quick start

import auth9token "github.com/db9-ai/auth9token-go"

cache, err := auth9token.NewJWKSCache(
    "https://auth.example.com/.well-known/jwks.json",
    5*time.Minute,  // positive TTL
    30*time.Second, // negative (unknown-kid) TTL
)
if err != nil { /* bad URL, config error */ }

v, err := auth9token.NewVerifier(auth9token.Config{
    Keys:     cache,
    Issuer:   "https://auth.example.com", // required, exact match
    Audience: "my-service",               // required, aud membership
})
if err != nil { /* incomplete config */ }

res, err := auth9token.Verify[auth9token.ProvenanceClaims](ctx, v, token)
if err != nil {
    var verr *auth9token.Error
    if errors.As(err, &verr) {
        // verr.Reason: typed rejection (expired, bad_signature, ...)
    }
    return
}
// res.Claims: issuer-attested top-level claims.
// res.Claims.Caller() / CallerClaim(): caller-asserted passthrough — never
// readable as attested fact.

Design notes worth knowing before deploying:

  • Issuer is required. An empty Config.Issuer is a construction error: an unpinned issuer would accept a validly-signed token from a different trust domain sharing the same JWKS.
  • exp is required. A token without an expiry is rejected as expired.
  • JWKS URL is validated at constructionhttps, or http on loopback only.

Conformance fixtures

conformance/fixtures.json is generated by the auth9 issuer from its real minting paths and vendored here on release: a JWKS (test key — public half only) plus accept/reject vectors with canonical rejection reasons. This repo's tests run every vector through the shipped verifier, so drift between what the issuer mints and what this library accepts fails in CI.

Consumers with their own verification stack can replay the same bundle: build a key source from jwks, pin meta.issuer / meta.audience, and assert each vector.expect verdict.

License

Apache-2.0. See LICENSE.

About

Go verifier for auth9-issued access tokens: JWKS fetching, RS256/ES256 verification, and claim-provenance readers, with issuer-generated conformance fixtures.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages