Skip to main content
from rubric import Governance
Governance owns the agent’s signed identity, the bundle cache, the audit sink, and the trace uploader. Most application code should use the decorator API instead — rubric.init() once, @rubric.tool per function. Reach for Governance directly when you need:
  • Multiple agents in one process. The singleton supports one identity at a time; Governance instances are independent.
  • Tests. Construct a Governance per test for isolation.
  • Library code. Don’t claim the process-wide singleton on a consumer’s behalf — accept a Governance via dependency injection.

Governance.bootstrap(...)

Class method that builds a fully-initialized instance.
@classmethod
def bootstrap(
    cls,
    *,
    enrollment_token: str | None = None,
    agent_name: str | None = None,
    api_url: str | None = None,
    bundle_poll_seconds: float = 30.0,
    autostart: bool = True,
    dlp: bool | DlpMode | Detector | None = None,
) -> "Governance":

Parameters

ParamTypeDefaultNotes
enrollment_tokenstr | NoneAG_ENROLLMENT_TOKEN envRequired. Long-lived org token. Mint one in Enrollment.
agent_namestr | NoneAG_AGENT_NAME envRequired. Stable name → stable identity. Same name across restarts reuses the same identity row.
api_urlstr | NoneAG_API_URL envThe Rubric API URL we gave you during onboarding.
bundle_poll_secondsfloat30.0How often to poll for new bundle versions.
autostartboolTrueStart the audit sink and bundle poller immediately.
dlpbool | DlpMode | Detector | NoneAG_DLP env or NoneDLP detector. See DLP.

Bootstrap resolution

Both enrollment_token and agent_name are required. If either is missing (after env-var fallback), bootstrap() raises ValueError — the SDK will not start unauthenticated.

Example

from rubric import Governance

with Governance.bootstrap(agent_name="payments-bot") as gov:
    # AG_ENROLLMENT_TOKEN read from env automatically
    ...

Lifecycle

Governance is a context manager. The recommended pattern:
with Governance.bootstrap(agent_name="my-bot") as gov:
    # Optional: block until first bundle pull completes
    gov.wait_until_ready(timeout=10.0)

    # ...your agent loop...
The with block calls gov.shutdown() automatically on exit, which:
  • Stops the bundle poller.
  • Flushes any queued audit events.
  • Closes the trace uploader’s HTTP session.
  • Stops the JWT refresh thread.

Properties

agent_id: str

The stable id bound to the JWT’s sub claim. Set on bootstrap; never changes.
print(gov.agent_id)
# payments-bot

current_bundle: Bundle | None

The most recently pulled policy bundle. None until the first pull completes.
gov.wait_until_ready(timeout=10.0)
b = gov.current_bundle
print(f"v{b.bundleVersion} with {len(b.policies)} policies")

Methods

wait_until_ready(timeout=10.0) -> bool

Block until the first bundle pull completes (success or failure). Returns True if a bundle was pulled, False on timeout. Optional — evaluate() is safe to call before the first pull (default-allow). But if you want your agent to stop and wait for policies, call this first.

evaluate(tool_name, *, session_id, ...) -> EvaluationResult

Evaluate a tool call against the current bundle and ship an audit event. See evaluate() for the full signature.

start() / shutdown()

Manual lifecycle for cases where the with block doesn’t fit (e.g., long-lived service classes). Don’t call start() more than once.

Without bootstrap

For tests and advanced flows, you can pass a pre-built TokenStore:
from rubric import Governance
from rubric.identity import TokenStore

store = TokenStore(...)  # already initialized
gov = Governance(token_store=store, api_url="https://api.your-rubric-url.example.com")
Reserve this for tests. In application code, always use bootstrap().