Skip to main content

Go SDK

The Go SDK provides typed helpers for the full pre-execution authorization flow: create a client, authorize an action, handle the three outcomes, and verify the permit before execution.

Install

go get github.com/veritrellis/sdk-go

Requires Go 1.21 or later.

import veritrellis "github.com/veritrellis/sdk-go"

Quick reference

SymbolPurpose
veritrellis.NewClient(cfg)Initialize a scoped client
client.Authorize(ctx, params)Submit an action for authorization
client.VerifyPermit(ctx, permit)Verify a permit JWT
client.PollPermit(ctx, requestID)Poll for a pending permit

Create a client

client.go
package main

import (
"os"

veritrellis "github.com/veritrellis/sdk-go"
)

func main() {
client := veritrellis.NewClient(veritrellis.Config{
APIKey: os.Getenv("VERITRELLIS_API_KEY"),
WorkspaceID: os.Getenv("VERITRELLIS_WORKSPACE_ID"),
Environment: "sandbox", // "sandbox" | "production"
APIURL: "https://api.veritrellis.ai",
})
_ = client
}

Configuration

FieldTypeRequiredDescription
APIKeystringYesWorkspace API key (vt_sandbox_… or vt_prod_…)
WorkspaceIDstringYesYour workspace ID (ws_…)
EnvironmentstringYes"sandbox" or "production"; must match the API key
APIURLstringNoDefaults to https://api.veritrellis.ai

Authorize an action

Call this before any action that requires a permit. It contacts the Veritrellis API and returns one of three outcomes. Always check err.

refund.go
result, err := client.Authorize(ctx, veritrellis.AuthorizeParams{
ActionType: "issue_refund",
ResourceRef: "cus_123",
Payload: map[string]any{
"customer_id": "cus_123",
"amount": 75,
"currency": "EUR",
"reason": "customer request",
},
})
if err != nil {
return err
}

Handling the three outcomes

handle_outcomes.go
switch result.Decision {
case "allowed":
// Permit is ready — verify it before executing
claims, err := client.VerifyPermit(ctx, result.Permit)
if err != nil {
return err
}
// Proceed with the action using verified claims
if err := issueRefund(claims); err != nil {
return err
}

case "pending_approval":
// Save result.RequestID and poll GET /v1/permits/:requestID
if err := saveForPolling(result.RequestID); err != nil {
return err
}

case "denied":
// Policy blocked this request — do not execute
return fmt.Errorf("action denied: %s", result.ReasonCode)
}
Always verify the permit

Receiving a Permit from Authorize is not sufficient. You must call VerifyPermit before executing the action. Permits that fail verification must not unlock execution.

Request parameters

FieldTypeRequiredDescription
ActionTypestringYesThe canonical action type (e.g. issue_refund)
ResourceRefstringYesIdentifier of the resource being acted on
Payloadmap[string]anyYesAction-specific fields; validated against shared schemas
ActorRefstringNoID of the human or agent initiating the action
IdempotencyKeystringNoStable key for safe retries

Response shape

FieldPresent whenTypeDescription
DecisionAlwaysstring"allowed", "pending_approval", or "denied"
RequestIDAlwaysstringUnique request identifier
Permitallowed onlystringSigned ES256 permit JWT
ReasonCodedenied onlystringMachine-readable denial reason

Verify a permit

Verifies a permit JWT against the workspace JWKS using golang-jwt/jwt/v5 internally. The client already holds the workspace ID and issuer, so it takes only the context and the permit. Returns an error if the signature, issuer, audience, or expiry check fails.

verify.go
claims, err := client.VerifyPermit(ctx, result.Permit)
if err != nil {
return err
}

The returned claims contains:

ClaimTypeDescription
SubstringRequest ID this permit is bound to
WorkspaceIDstringWorkspace the permit was issued for
ActionTypestringAction type the permit authorizes
ResourceRefstringResource the permit is scoped to
IssuedAtint64Issued-at timestamp (Unix)
ExpiresAtint64Expiry timestamp (Unix)

Polling for a permit

When Decision is pending_approval, poll until the request resolves:

poll.go
permit, err := client.PollPermit(ctx, result.RequestID)
if err != nil {
return err
}
// Ready — verify before executing
claims, err := client.VerifyPermit(ctx, permit)
if err != nil {
return err
}

PollPermit returns the permit once approved, and returns an error if the request is denied or expires.


Environment variables

VariableRequiredDescription
VERITRELLIS_API_KEYYesAPI key from the admin app
VERITRELLIS_WORKSPACE_IDYesWorkspace ID from the admin app
Using .env files

Both the API key and workspace ID are available in the admin app under Settings > API keys. The sandbox and production environments have separate keys.


Source