valiss

command module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 9, 2026 License: MIT Imports: 11 Imported by: 0

README

valiss

VALidator-ISSuer: tenant authentication for gRPC and HTTP services, modeled on NATS operator/user credentials.

  • An issuer holds an Ed25519 nkey; its public key is the trust anchor.
  • The issuer signs each tenant a scoped, time-limited JWT that binds the tenant's own nkey public key. Issued token ids go in a server-side allowlist.
  • The tenant signs every request with its nkey over a timestamp. The server verifies the token against the issuer key, the signature against the bound key within a skew window, and the token id against the allowlist, then hands the tenant identity to the handler for data segmentation.

(In nkeys terms the issuer key is an operator-type key: SO... seed, O... public key.)

Per-method authorization: grant call:<fullMethod> scopes (prefix wildcards like call:/pkg.Service/* and call:* supported) and enable WithMethodScope() on the authenticator.

Layout

main.go at the root is the CLI; the consumable library lives under pkg/.

  • pkg/token — token issue/verify, request sign/verify, allowlist, the credential Verifier, and TenantFromContext
  • pkg/creds — client credential bundle file (token + seed)
  • pkg/grpcauth — gRPC server interceptors and client per-RPC credentials
  • pkg/httpauth — net/http server middleware and client transport
  • internal/manifest — the valiss.yaml token manifest (CLI-only)
  • examples/ — runnable end-to-end demos for both transports

Library

Server (gRPC):

verifier := token.NewVerifier(issuerPubKey, allowlist)
auth := grpcauth.NewAuthenticator(verifier, grpcauth.WithMethodScope())
srv := grpc.NewServer(
    grpc.UnaryInterceptor(auth.UnaryInterceptor()),
    grpc.StreamInterceptor(auth.StreamInterceptor()),
)
// in a handler:
claims, _ := token.TenantFromContext(ctx) // claims.TenantID segments data

Client (gRPC):

tok, seed, _ := creds.Load("acme.creds")
c, _ := grpcauth.NewCredentials(tok, seed)
conn, _ := grpc.NewClient(addr, grpc.WithPerRPCCredentials(c), ...)

Server (HTTP):

mw := httpauth.NewMiddleware(token.NewVerifier(issuerPubKey, allowlist))
srv := &http.Server{Handler: mw(mux)}

Client (HTTP):

tok, seed, _ := creds.Load("acme.creds")
transport, _ := httpauth.NewTransport(tok, seed, nil)
client := &http.Client{Transport: transport}

Runnable versions: go run ./examples/grpcauth, go run ./examples/httpauth.

CLI

Stateless: seeds are printed once at generation and never stored; preserve them securely (a secrets manager, not this repo).

valiss keygen issuer       # one-time: public key = server trust anchor
valiss keygen tenant       # per-tenant: public key goes in valiss.yaml
valiss issue               # mint a token per manifest entry, YAML to stdout

issue reads the token manifest (valiss.yaml in the working directory, override with -f FILE) and signs with the issuer seed from -seed-file FILE or $VALISS_ISSUER_SEED:

# valiss.yaml — public data only, safe to commit
issuer: ODZ6U...        # issuer public key; issue refuses non-matching seeds
tokens:
  - id: acme
    key: ABPZ7...        # tenant public key from `valiss keygen tenant`
    scopes: ["call:/pkg.Svc/*"]
    ttl: 720h            # optional, defaults to 720h

An annotated template ships as valiss.example.yaml.

Output carries everything both sides need: the token for the client, the jti for the server-side allowlist:

tokens:
  - id: acme
    jti: FVIENQPFQY...   # add to the server allowlist
    expires: 2026-08-08T09:00:00Z
    token: eyJ0eXAiOiJKV1QiLCJhbGciOiJlZDI1NTE5LW5rZXkifQ...

Documentation

Overview

Command valiss issues tenant credentials for gRPC and HTTP services using the issuer/tenant nkey model (NATS operator/user style). It is stateless: seeds are printed once at generation and never stored; the caller preserves them securely.

valiss keygen issuer              # one-time: issuer key pair (trust anchor)
valiss keygen tenant              # per-tenant key pair
valiss issue                      # mint tokens for valiss.yaml entries

issue reads a token manifest (valiss.yaml in the working directory, override with -f) declaring the issuer public key and the tokens to mint (tenant id, public key, scopes, ttl), signs a token per entry with the issuer seed (-seed-file or $VALISS_ISSUER_SEED, which must match the manifest issuer), and writes the results to stdout as YAML. The jti of each token is what the server-side allowlist accepts.

Directories

Path Synopsis
examples
grpcauth command
Example grpcauth shows the full tenant-auth wiring for gRPC: an issuer issues a scoped token, the server installs the auth interceptors, and the client attaches the credential to every call.
Example grpcauth shows the full tenant-auth wiring for gRPC: an issuer issues a scoped token, the server installs the auth interceptors, and the client attaches the credential to every call.
httpauth command
Example httpauth shows the full tenant-auth wiring for net/http: an issuer signs a scoped token, the server wraps its mux with the auth middleware, and the client signs every request via the transport.
Example httpauth shows the full tenant-auth wiring for net/http: an issuer signs a scoped token, the server wraps its mux with the auth middleware, and the client signs every request via the transport.
internal
manifest
Package manifest reads the valiss.yaml token manifest: the public, non-secret description of every token to issue (issuer public key, tenant ids and public keys, scopes, ttls).
Package manifest reads the valiss.yaml token manifest: the public, non-secret description of every token to issue (issuer public key, tenant ids and public keys, scopes, ttls).
pkg
creds
Package creds implements the client credential bundle file: an issuer-signed token paired with the tenant seed that must sign requests, modeled on the nsc creds format.
Package creds implements the client credential bundle file: an issuer-signed token paired with the tenant seed that must sign requests, modeled on the nsc creds format.
grpcauth
Package grpcauth wires the tenant authentication scheme into gRPC: server interceptors that verify the per-request credential and a client per-RPC credential that attaches it.
Package grpcauth wires the tenant authentication scheme into gRPC: server interceptors that verify the per-request credential and a client per-RPC credential that attaches it.
httpauth
Package httpauth wires the tenant authentication scheme into net/http: a server middleware that verifies the per-request credential and a client http.RoundTripper that attaches it.
Package httpauth wires the tenant authentication scheme into net/http: a server middleware that verifies the per-request credential and a client http.RoundTripper that attaches it.
token
Package token implements the core of the tenant authentication scheme, modeled on NATS operator/user credentials:
Package token implements the core of the tenant authentication scheme, modeled on NATS operator/user credentials:

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL