Security
This page covers the SDK's security surface — TLS defaults, the expectedSender guardrail, and SDK-level retry behaviour for rate limits. The runtime is the source of truth for authentication, authorization, isolation, replay protection, rate limiting, and audit logging.
- Runtime API § Authentication
- Runtime API § Rate Limiting
- Runtime Deployment § Authentication
- Runtime Policy § Commitment authority
- Per-mode authorization rules: Runtime Modes
For the SDK-side AuthConfig API and identity-mismatch guardrail, see Authentication.
Transport security
TLS is on by default (RFC-MACP-0006 (Transport Bindings) §3). The constructor throws MacpSdkError if you pass secure: false without the explicit dev-only allowInsecure: true escape hatch, so plaintext can never ship accidentally:
import * as fs from 'fs';
// Production (TLS is implicit, but you may pin a CA)
const client = new MacpClient({
address: 'runtime.example.com:50051',
rootCertificates: fs.readFileSync('/path/to/ca.pem'),
auth: Auth.bearer('tok-prod-123', { expectedSender: 'my-agent' }),
});
// Local dev against MACP_ALLOW_INSECURE=1
const dev = new MacpClient({
address: '127.0.0.1:50051',
secure: false,
allowInsecure: true, // must be paired with secure: false
auth: Auth.devAgent('my-agent'),
});For server-side TLS configuration (MACP_TLS_CERT_PATH, MACP_TLS_KEY_PATH), see Runtime Deployment. See Authentication § TLS for this SDK's full transport-security walkthrough.
Sender identity guardrail
The runtime binds the envelope sender from the authenticated identity and rejects any mismatch. The SDK additionally enforces expectedSender client-side so spoofed senders fail before the envelope leaves the process, surfacing as MacpIdentityMismatchError rather than an opaque UNAUTHENTICATED:
const auth = Auth.bearer('tok-alice', { expectedSender: 'alice' });
const session = new DecisionSession(client, { auth });
await session.vote({ proposalId: 'p1', vote: 'approve' }); // sender defaults to 'alice' — OK
await session.vote({ proposalId: 'p1', vote: 'approve', sender: 'mallory' });
// ↑ throws MacpIdentityMismatchError { expectedSender: 'alice', actualSender: 'mallory' }Always set expectedSender in production. See Authentication § Identity guard for the full pattern, including per-operation auth overrides for multi-participant agents.
Retrying rate limits and transient failures
The runtime enforces per-sender rate limits and returns RATE_LIMITED when exceeded. The SDK ships RetryPolicy + retrySend() for safe exponential-backoff retries (idempotency keys make this safe — see the protocol spec's envelope model):
import { retrySend, type RetryPolicy } from 'macp-sdk-typescript';
const policy: RetryPolicy = {
maxRetries: 5,
backoffBase: 0.5,
backoffMax: 2.0,
retryableCodes: new Set(['RATE_LIMITED', 'INTERNAL_ERROR']),
};
await retrySend(client, envelope, { policy, auth });Limit defaults and environment variables: Runtime API § Rate Limiting. See Error Handling § Built-in Retry for this SDK's full retry-policy walkthrough, including DEFAULT_RETRY_POLICY.
SDK-side production checklist
Runtime-side hardening (TLS keys, audit logging, token storage, rate-limit tuning) is covered in Runtime Deployment § Production checklist. The items below are SDK-specific:
- Use TLS (the default) — never pass
allowInsecure: truein prod - Set
expectedSenderon everyAuth.bearercall so sender spoofing fails fast (MacpIdentityMismatchError) - Use real bearer tokens — never
Auth.devAgentin prod - When sending as multiple participants, scope auth per call (see Authentication § Per-Operation Auth)
- Wrap network calls in
retrySend()with aRetryPolicythat excludes permanent codes (FORBIDDEN,INVALID_ENVELOPE) - Use
SessionLifecycleWatcherfor supervisor visibility rather than pollinggetSession()(see Streaming § Session Lifecycle Watcher)