| title | SDK Reference |
|---|---|
| description | Client libraries for interacting with the SINT Protocol gateway. Available in TypeScript, Python, and Go. |
| sidebarTitle | SDKs |
All SDKs wrap the SINT Protocol REST API and connect to a running gateway server instance. They handle token serialization, request signing, and HTTP transport.
`@sint/client` — Node.js and browser. 12 tests. `sint-client` — Async-first via httpx. 1,962 lines. `sintclient` — Idiomatic Go with context support.Package: @sint/client
Source: sdks/typescript/ in the sint-protocol monorepo
Tests: 12 tests in __tests__/client.test.ts
npm install @sint/client
# or
pnpm add @sint/client
# or
yarn add @sint/clientimport { SintClient } from '@sint/client';
const client = new SintClient({
gatewayUrl: 'http://localhost:4100', // Required
apiKey: process.env.SINT_API_KEY, // Required for token creation
timeout: 5000, // Optional, default 5000ms
retries: 3, // Optional, default 3
});Creates a signed capability token authorizing an agent to perform an action.
const token = await client.createToken({
agentId: 'agent:my-assistant:v1', // Required
resource: 'payments:invoices', // Required, format: namespace:name
action: 'read', // Required: 'read' | 'write' | 'execute' | 'delete'
constraints: { // Optional, enforced at intercept time
maxAmount: 1000,
currency: 'USD',
allowedRegions: ['US', 'CA'],
},
tier: 'standard', // Optional: 'standard' | 'elevated' | 'restricted'
expiresIn: 3600, // Optional, seconds, default 3600
metadata: { // Optional, arbitrary key-value pairs
issuer: 'my-app',
environment: 'production',
},
});
// Returns:
// {
// token: 'sint_cap_01HXYZ...',
// tokenId: 'tok_01HXYZ...',
// agentId: 'agent:my-assistant:v1',
// resource: 'payments:invoices',
// action: 'read',
// constraints: { maxAmount: 1000, ... },
// tier: 'standard',
// issuedAt: Date,
// expiresAt: Date,
// signature: 'base64url_signature',
// }Validates a token and records the request in the ledger. Call this before executing any privileged action.
const result = await client.intercept({
token: 'sint_cap_01HXYZ...', // Required, the capability token string
resource: 'payments:invoices', // Required, must match token resource
action: 'read', // Required, must match token action
context: { // Optional, stored in ledger
requestId: 'req_01HXYZ...',
agentRuntime: 'openai-gpt-4',
sessionId: 'sess_01HXYZ...',
},
});
if (!result.allowed) {
// Handle denial — do NOT execute the action
throw new Error(`Access denied: ${result.reason}`);
// reason: 'TOKEN_EXPIRED' | 'TOKEN_REVOKED' | 'CONSTRAINT_VIOLATION' |
// 'RESOURCE_MISMATCH' | 'ACTION_MISMATCH' | 'INVALID_SIGNATURE'
}
// result.evidenceId — reference for audit trail
// result.ledgerEntry — full ledger recordCreates a child token from a parent token. The child token's permissions must be equal to or more restrictive than the parent.
const delegated = await client.delegateToken({
parentToken: 'sint_cap_01HXYZ...', // Required, the parent capability token
agentId: 'agent:sub-assistant:v1', // Required, the receiving agent
constraints: { // Must be subset of parent constraints
maxAmount: 100,
currency: 'USD',
},
expiresIn: 900, // Must not exceed parent expiry
metadata: {
delegatedBy: 'agent:my-assistant:v1',
},
});Revokes a token immediately. Any subsequent intercept() call with this token returns allowed: false.
await client.revokeToken('tok_01HXYZ...');
// Also revoke by token string
await client.revokeToken({ token: 'sint_cap_01HXYZ...' });Retrieves ledger entries. All parameters are optional filters.
const entries = await client.queryLedger({
agentId: 'agent:my-assistant:v1', // Filter by agent
tokenId: 'tok_01HXYZ...', // Filter by token
resource: 'payments:invoices', // Filter by resource
action: 'read', // Filter by action
result: 'allowed', // Filter: 'allowed' | 'denied'
since: new Date('2024-01-01'), // Start timestamp
until: new Date('2024-01-31'), // End timestamp
limit: 100, // Default 50, max 1000
offset: 0,
});
// entries.entries: LedgerEntry[]
// entries.total: number
// entries.limit: number
// entries.offset: numberGenerates a cryptographic proof that a specific action was allowed at a point in time. Useful for compliance audits.
const proof = await client.generateProof({
evidenceId: 'ev_01HXYZ...',
});
// Returns a signed proof object containing:
// - The original ledger entry
// - A Merkle proof for tamper-evidence
// - The gateway's signature
// Serialize with JSON.stringify(proof) for storage or transmissionimport { SintClient, SintError, SintAuthError, SintTokenError } from '@sint/client';
const client = new SintClient({ gatewayUrl: 'http://localhost:4100', apiKey: '...' });
try {
const result = await client.intercept({ token, resource, action });
} catch (err) {
if (err instanceof SintAuthError) {
// 401 — invalid or missing API key
} else if (err instanceof SintTokenError) {
// Token parsing or validation failure
} else if (err instanceof SintError) {
// Other gateway error
console.error(err.code, err.message, err.statusCode);
}
}Source: sdks/python/ in the sint-protocol repo
Size: ~1,962 lines
Runtime: Python 3.9+
Transport: httpx (async and sync)
pip install sint-client
# or with uv
uv add sint-clientSintClient — Primary client for gateway operations.
SintToken — Token model with validation and serialization methods.
PolicyGateway — Higher-level interface for policy enforcement patterns.
import asyncio
from sint import SintClient
async def main():
async with SintClient(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
timeout=5.0,
) as client:
token = await client.create_token(
agent_id="agent:my-assistant:v1",
resource="payments:invoices",
action="read",
)
print(token.token)
asyncio.run(main())from sint import SintClient
client = SintClient(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
)
token = client.create_token_sync(
agent_id="agent:my-assistant:v1",
resource="payments:invoices",
action="read",
)
print(token.token)import asyncio
import os
from sint import SintClient
from sint.exceptions import SintTokenDeniedError
async def main():
async with SintClient(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
) as client:
# Create a capability token
token = await client.create_token(
agent_id="agent:my-assistant:v1",
resource="payments:invoices",
action="read",
constraints={
"max_amount": 1000,
"currency": "USD",
},
tier="standard",
expires_in=3600,
)
# Intercept (validate + log) before executing
try:
result = await client.intercept(
token=token.token,
resource="payments:invoices",
action="read",
context={"request_id": "req_01HXYZ..."},
)
except SintTokenDeniedError as e:
print(f"Access denied: {e.reason}")
return
# Proceed with the actual operation
print(f"Allowed. Evidence ID: {result.evidence_id}")
asyncio.run(main())import os
from sint import PolicyGateway
# PolicyGateway wraps SintClient with middleware-style enforcement
gateway = PolicyGateway(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
)
# Decorator pattern — function only runs if intercept passes
@gateway.enforce(resource="payments:invoices", action="read")
async def read_invoice(invoice_id: str, *, sint_token: str) -> dict:
# This function only executes if the token is valid
return {"invoice_id": invoice_id, "amount": 500}
# Call with token — gateway validates before invoking
result = await read_invoice("inv_001", sint_token="sint_cap_01HXYZ...")import asyncio
import os
from sint import SintClient
from datetime import datetime, timedelta
async def main():
async with SintClient(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
) as client:
entries = await client.query_ledger(
agent_id="agent:my-assistant:v1",
since=datetime.utcnow() - timedelta(hours=24),
result_filter="denied",
limit=100,
)
for entry in entries.entries:
print(f"{entry.timestamp} {entry.resource} {entry.action}: {entry.result}")
# Generate a compliance proof
if entries.entries:
proof = await client.generate_proof(
evidence_id=entries.entries[0].evidence_id
)
print(f"Proof generated: {proof.signature[:20]}...")
asyncio.run(main())import asyncio
import os
from sint import SintClient
async def main():
async with SintClient(
gateway_url="http://localhost:4100",
api_key=os.environ["SINT_API_KEY"],
) as client:
parent = await client.create_token(
agent_id="agent:orchestrator:v1",
resource="data:records",
action="read",
constraints={"max_records": 10000},
expires_in=3600,
)
# Delegate restricted access to a subagent
child = await client.delegate_token(
parent_token=parent.token,
agent_id="agent:worker:v1",
constraints={"max_records": 100}, # More restrictive
expires_in=600, # Shorter TTL
)
print(f"Child token: {child.token}")
print(f"Expires: {child.expires_at}")
asyncio.run(main())from sint.types import (
CapabilityToken, # token, token_id, agent_id, resource, action, constraints, ...
InterceptResult, # allowed, reason, evidence_id, ledger_entry
LedgerEntry, # id, token_id, agent_id, resource, action, timestamp, result
LedgerPage, # entries, total, limit, offset
CryptoProof, # evidence_id, ledger_entry, merkle_proof, signature
)Source: sdks/go/ in the sint-protocol repo
Package: sintclient
Go version: 1.21+
go get github.com/sint-ai/sint-protocol/sdks/gopackage main
import (
"context"
"log"
"os"
"github.com/sint-ai/sint-protocol/sdks/go/sintclient"
)
func main() {
client, err := sintclient.NewClient(sintclient.Config{
GatewayURL: "http://localhost:4100",
APIKey: os.Getenv("SINT_API_KEY"),
Timeout: 5 * time.Second,
})
if err != nil {
log.Fatalf("failed to create client: %v", err)
}
defer client.Close()
}ctx := context.Background()
token, err := client.CreateToken(ctx, sintclient.CreateTokenParams{
AgentID: "agent:my-assistant:v1",
Resource: "payments:invoices",
Action: sintclient.ActionRead,
Constraints: map[string]interface{}{
"maxAmount": 1000,
"currency": "USD",
},
Tier: sintclient.TierStandard,
ExpiresIn: 3600,
})
if err != nil {
log.Fatalf("create token: %v", err)
}
log.Printf("Token: %s", token.Token)
log.Printf("Expires: %s", token.ExpiresAt.Format(time.RFC3339))ctx := context.Background()
result, err := client.Intercept(ctx, sintclient.InterceptParams{
Token: "sint_cap_01HXYZ...",
Resource: "payments:invoices",
Action: sintclient.ActionRead,
Context: map[string]string{
"requestId": "req_01HXYZ...",
"caller": "myapp",
},
})
if err != nil {
log.Fatalf("intercept error: %v", err)
}
if !result.Allowed {
log.Printf("Access denied: %s", result.Reason)
return
}
log.Printf("Allowed. Evidence: %s", result.EvidenceID)ctx := context.Background()
page, err := client.QueryLedger(ctx, sintclient.LedgerQueryParams{
AgentID: "agent:my-assistant:v1",
Limit: 100,
Offset: 0,
})
if err != nil {
log.Fatalf("query ledger: %v", err)
}
log.Printf("Total entries: %d", page.Total)
for _, entry := range page.Entries {
log.Printf("%s %s %s → %s",
entry.Timestamp.Format(time.RFC3339),
entry.Action,
entry.Resource,
entry.Result,
)
}package main
import (
"context"
"log"
"os"
"time"
"github.com/sint-ai/sint-protocol/sdks/go/sintclient"
)
func main() {
client, err := sintclient.NewClient(sintclient.Config{
GatewayURL: "http://localhost:4100",
APIKey: os.Getenv("SINT_API_KEY"),
Timeout: 5 * time.Second,
})
if err != nil {
log.Fatalf("init client: %v", err)
}
defer client.Close()
ctx := context.Background()
// 1. Issue token
token, err := client.CreateToken(ctx, sintclient.CreateTokenParams{
AgentID: "agent:go-worker:v1",
Resource: "storage:blobs",
Action: sintclient.ActionWrite,
ExpiresIn: 1800,
})
if err != nil {
log.Fatalf("create token: %v", err)
}
// 2. Validate before use
result, err := client.Intercept(ctx, sintclient.InterceptParams{
Token: token.Token,
Resource: "storage:blobs",
Action: sintclient.ActionWrite,
})
if err != nil {
log.Fatalf("intercept: %v", err)
}
if !result.Allowed {
log.Fatalf("denied: %s", result.Reason)
}
log.Printf("Proceeding with write. Evidence: %s", result.EvidenceID)
}// Actions
sintclient.ActionRead = "read"
sintclient.ActionWrite = "write"
sintclient.ActionExecute = "execute"
sintclient.ActionDelete = "delete"
// Tiers
sintclient.TierStandard = "standard"
sintclient.TierElevated = "elevated"
sintclient.TierRestricted = "restricted"
// Denial reasons
sintclient.ReasonTokenExpired = "TOKEN_EXPIRED"
sintclient.ReasonTokenRevoked = "TOKEN_REVOKED"
sintclient.ReasonConstraintViolation = "CONSTRAINT_VIOLATION"
sintclient.ReasonResourceMismatch = "RESOURCE_MISMATCH"
sintclient.ReasonActionMismatch = "ACTION_MISMATCH"
sintclient.ReasonInvalidSignature = "INVALID_SIGNATURE"| Feature | TypeScript | Python | Go |
|---|---|---|---|
createToken |
✅ | ✅ | ✅ |
intercept |
✅ | ✅ | ✅ |
delegateToken |
✅ | ✅ | — |
revokeToken |
✅ | ✅ | — |
queryLedger |
✅ | ✅ | ✅ |
generateProof |
✅ | ✅ | — |
| Async support | ✅ | ✅ | ✅ (context) |
| Retry logic | ✅ | ✅ | — |
| Type safety | Full | Full (hints) | Full |
| Browser support | ✅ | ❌ | ❌ |