Certificate-based security contexts for Go.
Turn mTLS certificates into typed authorization tokens with permissions, metadata, and delegatable guards.
Your PKI already establishes identity. sctx turns that identity into authorization.
// Define how certificates map to permissions
admin.SetPolicy(func(cert *x509.Certificate) (*sctx.Context[UserMeta], error) {
return &sctx.Context[UserMeta]{
Permissions: permissionsFromOU(cert.Subject.OrganizationalUnit),
Metadata: UserMeta{TenantID: cert.Subject.Organization[0]},
ExpiresAt: time.Now().Add(time.Hour),
}, nil
})
// Client proves key possession, gets a signed token
assertion, _ := sctx.CreateAssertion(clientKey, clientCert)
token, _ := admin.Generate(ctx, clientCert, assertion)
// Token holder creates guards for specific permissions
guard, _ := admin.CreateGuard(ctx, token, "api:read", "api:write")
// Guards validate other tokens
err := guard.Validate(ctx, incomingToken)No JWT parsing. No external identity provider. Your certificates are your identity system.
go get github.com/zoobzio/sctxRequires Go 1.24+.
package main
import (
"context"
"crypto/ed25519"
"crypto/x509"
"fmt"
"time"
"github.com/zoobzio/sctx"
)
type UserMeta struct {
Role string
TenantID string
}
func main() {
ctx := context.Background()
// Create the admin service with your signing key and trusted CAs
admin, _ := sctx.NewAdminService[UserMeta](privateKey, trustedCAPool)
// Define authorization policy: certificate -> context
admin.SetPolicy(func(cert *x509.Certificate) (*sctx.Context[UserMeta], error) {
return &sctx.Context[UserMeta]{
Permissions: []string{"read", "write"},
Metadata: UserMeta{Role: "admin", TenantID: cert.Subject.Organization[0]},
ExpiresAt: time.Now().Add(time.Hour),
}, nil
})
// Client creates assertion proving key possession
assertion, _ := sctx.CreateAssertion(clientKey, clientCert)
// Admin generates signed token
token, _ := admin.Generate(ctx, clientCert, assertion)
// Create a guard for specific permissions
guard, _ := admin.CreateGuard(ctx, token, "read")
// Validate tokens against the guard
if err := guard.Validate(ctx, token); err != nil {
fmt.Println("Access denied:", err)
return
}
fmt.Println("Access granted")
}| Feature | Description | Docs |
|---|---|---|
| Policy-Driven Authorization | Transform certificates into contexts with custom policies | Policy |
| Permission Guards | Create guards that check for required permissions | Guards |
| Type-Safe Metadata | Generic contexts with compile-time type checking | Concepts |
| Instant Revocation | Revoke contexts by certificate fingerprint | Revocation |
| Observability | Capitan events for all operations | Events |
| Testing Utilities | Deterministic testing with mock certificates | Testing |
- Certificate-native — Built on mTLS, no separate identity layer
- Type-safe — Generic metadata with compile-time checking
- Delegatable — Token holders create guards for others to use
- Zero shared secrets — Only public keys needed for validation
- Instantly revocable — Revoke by fingerprint, all guards reject immediately
- Observable — Every operation emits capitan events
sctx enables a pattern: certificates establish identity, policies define permissions, guards enforce access.
Your mTLS infrastructure already verifies who clients are. sctx adds what they can do.
// In your mTLS handler — certificate is already verified
func handler(w http.ResponseWriter, r *http.Request) {
cert := r.TLS.PeerCertificates[0]
// Turn certificate into authorization token
assertion, _ := sctx.CreateAssertion(clientKey, cert)
token, _ := admin.Generate(r.Context(), cert, assertion)
// Check permissions with a guard
if err := readGuard.Validate(r.Context(), token); err != nil {
http.Error(w, "Forbidden", http.StatusForbidden)
return
}
// Authorized — proceed
}One certificate, one policy, full authorization. No JWT middleware. No token introspection endpoints.
- Overview — Design philosophy and architecture
- Quickstart — Get started in minutes
- Concepts — Contexts, tokens, guards, assertions
- Architecture — Internal design and components
- Policy — Certificate-to-context transformation
- Guards — Permission checking and delegation
- Events — Observability with capitan
- Testing — Testing with mock certificates
- mTLS Integration — HTTP handlers with certificate auth
- RBAC Patterns — Role-based access control
- Revocation — Instant token invalidation
See CONTRIBUTING.md for guidelines. Run make help for available commands.
MIT License — see LICENSE for details.