evaluate()) that your tool dispatcher invokes.
What the SDK does
The SDK has three responsibilities, all of which run in your process without blocking your tool dispatch.Evaluator
evaluate() is sub-millisecond — it interprets your policy bundle against the tool call’s metadata and returns allow / deny synchronously, without a network round-trip on the hot path. Bundles are pre-compiled when received so regex evaluation is a constant-time operation per call.
Bundle cache
A background poller refreshes the bundle every 30 seconds. The bundle is kept in memory and used for every evaluation until the next poll succeeds. If Rubric is unreachable, the SDK keeps using the last-known-good bundle — your agent continues to enforce policy even during a network outage. The bundle is content-hashed; the poller sends?since=<hash> so unchanged bundles return 304 Not Modified instead of re-downloading. Incoming bundles are also checked for version monotonicity: a bundle whose bundleVersion is lower than the cached one, or whose builtAt is significantly older, is rejected to defeat rollback attempts.
Audit sink
Everyevaluate() enqueues an audit event into an in-memory queue. A background flush task batches events and ships them — default cadence is every second or 100 events, whichever comes first. Your code never waits on the network.
If the queue fills (default cap: 10,000 events) or repeated ship failures exhaust retries, events are dropped and a counter increments. The counters are surfaced through getStats() so your monitoring can alarm on silent drops.
Identity
On startup the SDK exchanges your enrollment token for a short-lived (60 minute) signed identity. A background task refreshes it ahead of expiry. The signed identity is what authenticates the bundle pulls and audit uploads — your enrollment token is only used at boot.What gets sent over the wire
The SDK makes three classes of HTTPS request:| Request | Purpose |
|---|---|
POST /v1/identities/enroll / …/refresh | Exchange the enrollment token for a signed identity; refresh it before expiry. |
GET /v1/bundle?since=<hash> | Pull the latest policy bundle scoped to this agent. |
POST /v1/events | Ship batched audit events. |
Trust model
| Credential | Issued to | Can do | Cannot do |
|---|---|---|---|
Enrollment token (enr_…) | Operators, via the dashboard | Bootstrap a new agent’s identity | Ship audit events, read bundles, impersonate an existing agent |
| Signed identity (60 min) | The SDK at boot, refreshed automatically | Pull the agent’s bundle; ship audit events attributed to that agent | Impersonate a different agent — Rubric rejects any event whose agent id doesn’t match the identity it was sent with |
Failure modes
| Failure | Behavior |
|---|---|
| Rubric API unreachable | SDK uses last-known-good bundle. Audit events queue in memory and flush on recovery. |
| Bundle stale | The SDK exposes lastPullAt and lastBundleChangeAt so your harness can enforce a max-age if you want to fail closed after a threshold. |
| Identity expires mid-outage | The refresh task retries with backoff. The still-valid identity continues working until it expires. |
| Process restart | Enrollment is idempotent on agentName — restarting returns the same agent id with a fresh signed token. |
| Identity revoked | Enrollment is rejected. Operator must un-revoke from the dashboard or pick a different agentName. |