Protect a Go net/http Service
Use the Go net/http adapter when a Go service should verify Caracal mandates at the handler boundary.
Prerequisites
Section titled “Prerequisites”- A mandate-aware resource with a stable audience and route scopes.
- STS issuer, zone ID, and a production Redis revocation consumer.
- Request deadlines on inbound handlers so JWKS or revocation work is cancelable.
Install
Section titled “Install”go get github.com/garudex-labs/caracal/packages/adapters/nethttp/gogo get github.com/garudex-labs/caracal/packages/revocation/goWrap a handler
Section titled “Wrap a handler”package main
import ( "encoding/json" "net/http" "time"
nethttp "github.com/garudex-labs/caracal/packages/adapters/nethttp/go" revocation "github.com/garudex-labs/caracal/packages/revocation/go" verify "github.com/garudex-labs/caracal/packages/verify/go")
func main() { revocations := revocation.NewInMemoryStore(24 * time.Hour)
verifier := verify.NewVerifier(verify.Options{ Issuer: "https://sts.pipernet.example", Audience: "resource://pipernet", ZoneID: "0195f2a9-1b22-7c3d-9e4f-5a6b7c8d9e0f", Revocations: revocations, })
protected := nethttp.VerifierMiddleware(verifier.Require(verify.Options{ RequiredScopes: []string{"pipernet:read"}, RequiredTargets: []string{"resource://pipernet"}, }))(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { claims, ok := nethttp.ClaimsFromContext(r.Context()) if !ok { http.Error(w, "missing claims", http.StatusUnauthorized) return } _ = json.NewEncoder(w).Encode(map[string]string{"subject": claims.Sub}) }))
http.Handle("/reports", protected) _ = http.ListenAndServe(":8080", nil)}Enforce constraints
Section titled “Enforce constraints”| Option | Use it for |
|---|---|
RequiredScopes | Route or operation permission. |
RequiredTargets | Resource target matching. |
RequireSession | Session-bound endpoints. |
RequireDelegation | Delegated-only endpoints. |
RequireChainContains | Application path requirements. |
MaxHopCount | Delegation depth limit. |
Production revocation
Section titled “Production revocation”The in-memory store does not share revocations across instances. Use the Redis revocation backend and consume caracal.sessions.revoke for production resource servers.
Validate
Section titled “Validate”- Call without a bearer token and expect
401. - Call with a valid mandate and expect the handler response.
- Remove a required scope and expect
403. - Mark the session revoked and expect
session_revoked.
Expected result: 401 identifies an unaccepted credential, 403 identifies accepted but insufficient authority, and ClaimsFromContext succeeds only inside protected handlers.
For exact Go fields, use net/http Adapter reference.
Next Step
Section titled “Next Step”Connect the Redis revocation consumer and validate it with Test Caracal Integrations.

