What valiss gives you
valiss authenticates services offline against one pinned public key. Each capability below is a property of that model, linked to the documentation that specifies it.
Trust model
Offline
verification
There is no issuer to consult at verification time. A verifier walks each credential from the pinned key down and checks every signature locally, with no network call.
One
pinned anchor
A server pins a single value, the operator public key. NewVerifier(operatorPub, allowlist) is the whole trust configuration; it holds no seed.
Role in the
key material
An nkey carries its role, so a verifier checks at every hop that an operator key signed the account token and an account key signed the user token. Cross-level confusion cannot be expressed.
Credentials that resist theft
Proof of
possession
A token authorizes nothing on its own. A request is authentic only if it is signed, per request, by the subject’s seed, so capturing a token off the wire does not let you act as its subject.
Delegation
cannot widen
An account seed can mint users, but never more scope than the account holds, and an account can never mint another account. A stolen account seed is a tenant breach, not a domain one.
Bearer tokens,
scoped narrowly
Only user tokens may waive the per-request signature, for clients that cannot hold a key. It is a deliberate weakening: pair with TLS and a short validity window.
Revocation and rotation
Fail-closed
allowlist
An account token is accepted only if its id is on the list you deposited. It is an explicit allowlist, not a denylist of revoked ids, so nothing is trusted by default.
Pluggable
allowlist sources
The Allowlist interface is a single Allowed(jti) method. Back it with a file swapped atomically, a database query, a cache, or a fully dynamic per-call policy.
Epoch
rotation
A self-signed operator token carries an epoch. Bump it and re-mint, and every token from an earlier epoch is rejected cryptographically, with no allowlist edits.
Multiple
trusted operators
A keyring verifies messages and requests from several independent trust domains, each entry a self-signed operator token with its own name, epoch, and window.
Authorization
Typed
extension grants
Authorization rides named extension claims: signed, typed payloads under the token’s ext field. The same concrete type comes back out on the server, with no string plumbing.
Transport
enforcement
The http and grpc integrations authorize through signed extensions and fail closed. Every token in the chain must carry the extension, and the zero value grants nothing.
Custom
domain extensions
Any struct with an ExtensionName method is signed opaquely and recovered as its concrete type in the handler. Optionally validate it inside the verification pipeline.
Proof of origin
Message
tokens
Extend the chain one level with short-lived tokens minted per emitted message. Any receiver verifies provenance offline knowing only the operator public key.
Signed
HTTP and gRPC
The httpsig and grpcsig contrib transports wire proof of origin end to end: a client mints a token per outgoing request, and a middleware or interceptor verifies it on the other side.
Replay and
tamper binding
A message token binds its destination with audience and its payload bytes with a checksum. A receiver sets ExpectAudience and WithPayload to close cross-destination replay and tampering.
Credentials and custody
Credential
files
A marker-delimited text file packages a client’s tokens and signing seed together, everything a client holds and nothing the server does. Parsing is strict and fails closed at the door.
Unidirectional
custody
The seed is the secret and lives only on the signing side. The server holds an operator public key and an allowlist, never a seed, so a verifier compromise cannot leak signing power.
Lean
creds or bundles
User creds can omit the account token and let a server resolver supply it, or embed it as a self-contained bundle. Pick by where you would rather hold the account token.
Languages and interoperability
Go, Python,
TypeScript
Go is the reference implementation. Python is a full client library at parity. TypeScript ships the sign and verify primitives from source, with no transport adapter yet.
Conformance
vectors
A frozen, append-only corpus pairs each artifact with its expected outcome. Every implementation ships an offline runner that must pass all of them. The vectors decide which implementation diverged.
Interoperability
gates
A live matrix runs server against client against transport across languages. A stable release must prove it interoperates with every other implementation before it can ship.