SDKs
Two official clients with the same shape: construct with an API key, then preflight() for decisions or guard() to gate real execution. Both fail closed on network errors.
TypeScript: @actpass/sdk
npm install @actpass/sdkThe minimal integration is six lines: construct a client, wrap the action:
import { createActPass } from '@actpass/sdk';
const actpass = createActPass({ apiKey: process.env.ACTPASS_API_KEY! });
const { decision, result } = await actpass.guard({
goal: 'resolve_refund_request', tool: 'stripe.refund.create',
args: { amount: 4900 }, execute: async () => doRefund(),
});import { createActPass } from '@actpass/sdk';
// createActPass(config) returns an ActPassClient - new ActPassClient(config) works too.
const actpass = createActPass({
apiKey: process.env.ACTPASS_API_KEY!,
tenantId: 'your-team-id', // optional routing hint (sent as x-actpass-tenant)
agentId: 'support_agent', // optional; defaults to 'sdk'
// baseUrl defaults to ACTPASS_API_BASE_URL, then the hosted API
// (https://www.api.actpass.org)
});Decide, then act: guard()
guard() runs preflight and only invokes your execute callback on allow (or warn). On anything else, deny, pending approval, or a drifted tool, your code simply doesn't run.
const { decision, result, error } = await actpass.guard({
goal: 'resolve_refund_request',
tool: 'stripe.refund.create',
resource: 'stripe:charge:ch_123',
args: { amount: 4900, currency: 'usd' },
mode: 'enforce',
execute: async ({ credential }) =>
stripe.refunds.create({ charge: 'ch_123', amount: 4900 }),
});
switch (decision.decision) {
case 'allow':
return result;
case 'require_approval':
return notify(`Held for review: ${decision.approval_request_id}`);
default:
log.warn(decision.reason_code, decision.explain.summary);
}Decision only: preflight()
const d = await actpass.preflight({
goal: 'send_status_update',
tool: 'gmail.send',
args: { to: 'customer@example.com' },
});
// d.decision, d.reason_code, d.risk_tier, d.explain.matched_rulesPassports
const { token } = await actpass.issuePassport({
audience: 'mcp://stripe-production',
goal: 'resolve_refund_request',
allowedTools: ['stripe.refund.create'],
allowedResources: ['stripe:charge:ch_123'],
resourceConstraints: { max_amount: 10000, currency: 'usd' },
});
// pass `token` as `passport` in preflight/guard calls
await actpass.verifyPassport({ token, audience: 'mcp://stripe-production' });
await actpass.revokePassport('ap_...', 'session ended'); // by jtiCustom audit events go through recordEvidence(). For coding-agent gateways, the package also exports an ActPass interceptor class whose enforcePolicy() maps decisions onto ALLOWED | BLOCKED | PENDING_HUMAN_REVIEW with a 5-second fail-closed timeout, and runInstall(), the programmatic equivalent of actpass install device pairing.
Python: actpass
pip install actpassimport os
from actpass import ActPassClient
client = ActPassClient(
api_key=os.environ["ACTPASS_API_KEY"],
tenant_id="your-team-id",
agent_id="support_agent",
)
# Decision only
d = client.preflight(
goal="resolve_refund_request",
tool="stripe.refund.create",
args={"amount": 4900, "currency": "usd"},
resource="stripe:charge:ch_123",
)
print(d["decision"], d["reason_code"])
# Gate real execution
out = client.guard(
goal="resolve_refund_request",
tool="stripe.refund.create",
args={"amount": 4900, "currency": "usd"},
execute_fn=lambda ctx: stripe.Refund.create(charge="ch_123", amount=4900),
)The Python client mirrors the TypeScript surface: issue_passport(), verify_passport(), revoke_passport(), and record_evidence() for custom audit events, plus a create_actpass() factory where only api_key is required.
mode: "monitor" during rollout if you need observe-only behavior.