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
| Symbol | Purpose |
|---|---|
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
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
| Field | Type | Required | Description |
|---|---|---|---|
APIKey | string | Yes | Workspace API key (vt_sandbox_… or vt_prod_…) |
WorkspaceID | string | Yes | Your workspace ID (ws_…) |
Environment | string | Yes | "sandbox" or "production"; must match the API key |
APIURL | string | No | Defaults 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.
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
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)
}
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
| Field | Type | Required | Description |
|---|---|---|---|
ActionType | string | Yes | The canonical action type (e.g. issue_refund) |
ResourceRef | string | Yes | Identifier of the resource being acted on |
Payload | map[string]any | Yes | Action-specific fields; validated against shared schemas |
ActorRef | string | No | ID of the human or agent initiating the action |
IdempotencyKey | string | No | Stable key for safe retries |
Response shape
| Field | Present when | Type | Description |
|---|---|---|---|
Decision | Always | string | "allowed", "pending_approval", or "denied" |
RequestID | Always | string | Unique request identifier |
Permit | allowed only | string | Signed ES256 permit JWT |
ReasonCode | denied only | string | Machine-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.
claims, err := client.VerifyPermit(ctx, result.Permit)
if err != nil {
return err
}
The returned claims contains:
| Claim | Type | Description |
|---|---|---|
Sub | string | Request ID this permit is bound to |
WorkspaceID | string | Workspace the permit was issued for |
ActionType | string | Action type the permit authorizes |
ResourceRef | string | Resource the permit is scoped to |
IssuedAt | int64 | Issued-at timestamp (Unix) |
ExpiresAt | int64 | Expiry timestamp (Unix) |
Polling for a permit
When Decision is pending_approval, poll until the request resolves:
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
| Variable | Required | Description |
|---|---|---|
VERITRELLIS_API_KEY | Yes | API key from the admin app |
VERITRELLIS_WORKSPACE_ID | Yes | Workspace ID from the admin app |
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.