Skip to main content

Quick Start

#

Get from zero to a governed agent intent in under five minutes. This guide walks you through authentication, agent registration, your first intent submission, and reading the audit trail.

The production API is live at https://console.regulator.ai. All endpoints use the /api/v1 prefix. For self-hosted deployments, replace the base URL with your own.

Step 1: Authenticate & Get Your API Key#

Vienna OS supports session-based authentication for the operator console and API key authentication for programmatic access. Start by logging in to get a session token.

curl — Loginbash
curl -X POST https://console.regulator.ai/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "your-email@company.com",
    "password": "your-password"
  }'
Responsejson
{
  "success": true,
  "data": {
    "operator": {
      "id": "op-7f3a2b1c",
      "email": "your-email@company.com",
      "role": "admin",
      "organization": "your-org"
    },
    "sessionId": "sess-a8b3c2d1-4e5f-6789-abcd-ef0123456789",
    "apiKey": "vos_live_k1_7f3a2b1c9d4e5f6789abcdef01234567",
    "expiresAt": "2026-03-26T21:35:00.000Z"
  }
}

Store the apiKey securely. For all subsequent requests, include it as a Bearer token or pass the session cookie.

TypeScripttypescript
const VIENNA_API_KEY = process.env.VIENNA_API_KEY;
const BASE_URL = "https://console.regulator.ai";

const headers = {
  "Content-Type": "application/json",
  Authorization: `Bearer ${VIENNA_API_KEY}`,
};
Pythonpython
import os
import requests

VIENNA_API_KEY = os.environ["VIENNA_API_KEY"]
BASE_URL = "https://console.regulator.ai"

headers = {
    "Content-Type": "application/json",
    "Authorization": f"Bearer {VIENNA_API_KEY}",
}

Step 2: Register Your First Agent#

Before an agent can submit intents, it must be registered with a trust profile. This creates an identity in the fleet and assigns default permissions.

curl — Register Agentbash
curl -X POST https://console.regulator.ai/api/v1/fleet \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VIENNA_API_KEY" \
  -d '{
    "name": "support-agent-01",
    "description": "Customer support automation agent",
    "type": "autonomous",
    "trust_score": 50,
    "allowed_actions": ["send_email", "query_database", "create_ticket"],
    "metadata": {
      "framework": "langchain",
      "version": "0.1.0",
      "owner": "platform-team"
    }
  }'
Responsejson
{
  "success": true,
  "data": {
    "agent_id": "agt-9c8b7a6f-5e4d-3c2b-1a09-876543210fed",
    "name": "support-agent-01",
    "status": "active",
    "trust_score": 50,
    "api_key": "vos_agent_k1_9c8b7a6f5e4d3c2b1a09876543210fed",
    "created_at": "2026-03-25T21:35:00.000Z"
  }
}
The trust_score (0–100) determines baseline risk assessment. New agents start at 50. Vienna adjusts this score based on the agent's behavior over time. Higher trust scores may qualify for automatic approval on lower-risk actions.

Step 3: Submit an Intent#

Every action an agent wants to perform is submitted as an intent. The intent flows through the governance pipeline: validation → policy evaluation → risk tier assignment → approval (if required) → warrant issuance → execution → verification.

curl — Submit Intentbash
curl -X POST https://console.regulator.ai/api/v1/agent/intent \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VIENNA_AGENT_KEY" \
  -d '{
    "action": "send_email",
    "source": {
      "platform": "langchain",
      "agent_id": "agt-9c8b7a6f"
    },
    "tenant_id": "your-org",
    "parameters": {
      "to": "customer@example.com",
      "subject": "Your support ticket #1234",
      "body": "Hi, your ticket has been resolved."
    },
    "context": {
      "ticket_id": "TKT-1234",
      "conversation_id": "conv-5678",
      "reason": "Ticket resolution notification"
    }
  }'
Response — T0 (Auto-Approved)json
{
  "success": true,
  "data": {
    "intent_id": "int-2d4f6a8b-1c3e-5d7f-9a0b-c2d4e6f8a0b2",
    "status": "executed",
    "risk_tier": "T0",
    "execution_id": "exec-3e5f7a9b-2d4f-6a8c-0b1c-d3e5f7a9b1c3",
    "warrant": {
      "warrant_id": "wrt-4f6a8c0b-3e5f-7a9b-1c2d-e4f6a8c0b2d4",
      "scope": "send_email",
      "ttl": 300,
      "issued_at": "2026-03-25T21:35:01.000Z",
      "expires_at": "2026-03-25T21:40:01.000Z"
    },
    "verification": {
      "status": "passed",
      "scope_match": true,
      "verified_at": "2026-03-25T21:35:02.000Z"
    },
    "result": {
      "email_sent": true,
      "message_id": "msg-abc123"
    }
  }
}
Response — T1 (Approval Required)json
{
  "success": true,
  "data": {
    "intent_id": "int-5a7b9c0d-4e6f-8a1b-2c3d-f5a7b9c0d1e2",
    "status": "pending_approval",
    "risk_tier": "T1",
    "approval": {
      "approval_id": "apr-6b8c0d1e-5a7b-9c2d-3e4f-a6b8c0d1e2f3",
      "required_approvers": 1,
      "current_approvals": 0,
      "expires_at": "2026-03-25T22:35:00.000Z"
    }
  }
}
TypeScript — Full Exampletypescript
async function submitIntent(action: string, parameters: Record<string, unknown>) {
  const response = await fetch(`${BASE_URL}/api/v1/agent/intent`, {
    method: "POST",
    headers,
    body: JSON.stringify({
      action,
      source: { platform: "custom", agent_id: "agt-9c8b7a6f" },
      tenant_id: "your-org",
      parameters,
    }),
  });

  const data = await response.json();

  if (data.data.status === "pending_approval") {
    console.log(`⏳ Waiting for approval: ${data.data.approval.approval_id}`);
    // Poll or use webhooks to wait for approval
    return data.data;
  }

  if (data.data.status === "executed") {
    console.log(`✅ Executed: ${data.data.execution_id}`);
    console.log(`🔒 Warrant: ${data.data.warrant.warrant_id}`);
    return data.data;
  }

  if (data.data.status === "denied") {
    console.log(`❌ Denied by policy: ${data.data.reason}`);
    throw new Error(data.data.reason);
  }
}

// Usage
await submitIntent("send_email", {
  to: "customer@example.com",
  subject: "Ticket resolved",
  body: "Your issue has been fixed.",
});
Python — Full Examplepython
import requests

def submit_intent(action: str, parameters: dict) -> dict:
    response = requests.post(
        f"{BASE_URL}/api/v1/agent/intent",
        headers=headers,
        json={
            "action": action,
            "source": {"platform": "custom", "agent_id": "agt-9c8b7a6f"},
            "tenant_id": "your-org",
            "parameters": parameters,
        },
    )
    data = response.json()

    match data["data"]["status"]:
        case "executed":
            print(f"✅ Executed: {data['data']['execution_id']}")
            print(f"🔒 Warrant: {data['data']['warrant']['warrant_id']}")
        case "pending_approval":
            print(f"⏳ Awaiting approval: {data['data']['approval']['approval_id']}")
        case "denied":
            raise RuntimeError(f"❌ Denied: {data['data']['reason']}")

    return data["data"]

# Usage
submit_intent("send_email", {
    "to": "customer@example.com",
    "subject": "Ticket resolved",
    "body": "Your issue has been fixed.",
})

Step 4: View the Audit Trail#

Every intent, policy evaluation, warrant, execution, and verification is recorded in the append-only audit trail. Query it to see exactly what happened.

curl — Query Audit Trailbash
curl https://console.regulator.ai/api/v1/audit \
  -H "Authorization: Bearer $VIENNA_API_KEY" \
  -G \
  -d "limit=10" \
  -d "agent_id=agt-9c8b7a6f"
Responsejson
{
  "success": true,
  "data": {
    "entries": [
      {
        "id": "aud-7c9d0e1f",
        "timestamp": "2026-03-25T21:35:02.000Z",
        "type": "verification_complete",
        "intent_id": "int-2d4f6a8b",
        "execution_id": "exec-3e5f7a9b",
        "warrant_id": "wrt-4f6a8c0b",
        "agent_id": "agt-9c8b7a6f",
        "action": "send_email",
        "risk_tier": "T0",
        "result": "passed",
        "scope_compliance": true,
        "duration_ms": 847
      },
      {
        "id": "aud-6b8c0d1e",
        "timestamp": "2026-03-25T21:35:01.000Z",
        "type": "warrant_issued",
        "warrant_id": "wrt-4f6a8c0b",
        "scope": "send_email",
        "ttl": 300,
        "issuer": "system:auto-approve"
      }
    ],
    "total": 2,
    "has_more": false
  }
}
That's it. In four steps you've authenticated, registered an agent, submitted a governed intent through the full pipeline, and inspected the cryptographic audit trail. Every action your agents take is now governed, warranted, and verifiable.

Core Concepts

#

Vienna OS is built on seven foundational concepts. Understanding these is essential for integrating effectively and designing governance policies that match your organization's risk tolerance.

Intent Gateway#

The Intent Gateway is the single entry point for all agent actions. No agent communicates directly with external systems. Instead, every action is expressed as a declarative intent and submitted to the gateway.

This design is deliberate. By funneling all agent behavior through one point, Vienna can normalize, validate, and govern every action before it reaches execution. There are no side channels.

Intent Flowtext
┌─────────────────────────────────────────────────┐
│                 Intent Gateway                   │
│                                                  │
│  ┌──────────┐  ┌────────────┐  ┌─────────────┐  │
│  │ Normalize │→ │  Validate  │→ │ Deduplicate │  │
│  └──────────┘  └────────────┘  └─────────────┘  │
│                                       │          │
│                                       ↓          │
│                              ┌─────────────┐     │
│                              │ Enrich with  │     │
│                              │   context    │     │
│                              └─────────────┘     │
│                                       │          │
│                                       ↓          │
│                              Policy Engine       │
└─────────────────────────────────────────────────┘

Normalization. The gateway accepts intents from any framework — LangChain, CrewAI, AutoGen, or raw HTTP. It normalizes the payload into a canonical format regardless of source, so the policy engine evaluates a consistent schema.

Validation. Intents are validated against registered action types. If an agent submits an action not in its allowed set, the intent is rejected before reaching the policy engine. Parameters are type-checked against the action type schema.

Deduplication. The gateway detects and collapses duplicate intents within a configurable time window (default: 5s). This prevents runaway agents from flooding the pipeline.

Context enrichment. The gateway attaches metadata: agent trust score, historical behavior patterns, time-of-day, and organizational context. This enriched payload feeds into policy evaluation.

Policy Engine#

The Policy Engine is where governance rules live. Policies are defined as structured rules — not natural language, not LLM prompts, but deterministic code that evaluates in microseconds. Every intent is evaluated against the full policy set before any action is taken.

Rule Structure

A policy rule consists of conditions, an action, and a priority. Rules are evaluated in priority order (highest first). The first matching rule wins.

Policy Rule Schemajson
{
  "id": "pol-rule-001",
  "name": "Block high-value transactions after hours",
  "description": "Prevent financial actions over $10K outside business hours",
  "priority": 100,
  "enabled": true,
  "conditions": [
    {
      "field": "action",
      "operator": "equals",
      "value": "transfer_funds"
    },
    {
      "field": "parameters.amount",
      "operator": "gt",
      "value": 10000
    },
    {
      "field": "context.timestamp",
      "operator": "time_between",
      "value": ["18:00", "08:00"]
    }
  ],
  "action": {
    "type": "deny",
    "reason": "High-value transfers blocked outside business hours (8AM-6PM ET)"
  },
  "risk_tier_override": null
}

Evaluation Order

Rules are sorted by priority (descending). The first rule whose conditions all match determines the outcome. If no rule matches, the default policy applies (configurable: deny-by-default or allow-by-default).

Condition Operators

Vienna supports 14 condition operators for precise policy expression:

OperatorDescriptionExample Value
equalsExact match"transfer_funds"
not_equalsNegated exact match"read_only"
containsSubstring / array inclusion"admin"
gtGreater than (numeric)10000
ltLess than (numeric)100
gteGreater than or equal80
lteLess than or equal5
inValue in set["us","eu","uk"]
not_inValue not in set["sandbox","test"]
matchesRegex match"^prod-.*"
betweenNumeric range (inclusive)[100, 5000]
time_betweenTime-of-day range["09:00","17:00"]
existsField is present and non-nulltrue
not_existsField is absent or nulltrue

Risk Tiers#

Every intent is assigned a risk tier that determines the approval workflow. Tiers are assigned by the policy engine based on the action type, parameters, agent trust score, and contextual factors.

T0

Auto-Approved — Reversible / Low-Stakes

No human intervention. Warrant is issued automatically, action executes immediately.

• Read operations: log queries, status checks, health probes
• Internal queries: state graph reads, configuration lookups
• Non-destructive analytics: report generation, metric aggregation
• Low-value notifications: sending slack messages, logging events
T1

Single Approval — Moderate Stakes

One operator must approve before execution. Approval timeout is configurable (default: 1 hour). Escalation triggers if no response.

• Configuration changes: environment variables, feature flags
• Service operations: restarts, scaling, deployments to staging
• Data writes: customer record updates, ticket modifications
• External communications: emails to customers, API calls to partners
T2

Multi-Party Approval — Irreversible / High-Impact

Requires approval from multiple operators (configurable: 2–5 approvers). Warrants carry strict scope constraints and short TTLs (default: 5 min).

• Production deployments: code releases, infrastructure changes
• Financial operations: wire transfers, payment processing over threshold
• Data destruction: database migrations, record deletion, PII purges
• Legal actions: contract execution, regulatory filings, compliance reports

Tier assignment is dynamic. The same action can be T0 in one context and T1 in another. For example, send_email might be T0 for internal notifications but T1 for customer-facing messages. Policy rules control this.

Approval Workflows#

When an intent is classified as T1 or T2, it enters the approval queue. Operators are notified via the console, webhooks, or integrated channels (Slack, email).

Approval Flowtext
T1 — Single Operator Approval
─────────────────────────────
Intent → Policy Engine → T1 → Approval Queue
                                    │
                              ┌─────┴─────┐
                              │  Operator  │
                              │  Reviews   │
                              └─────┬─────┘
                                    │
                         ┌──────────┼──────────┐
                         │          │          │
                      Approve     Deny     Timeout
                         │          │          │
                      Warrant    Denied    Escalate
                      Issued     + Log    to T2 or
                         │                 Manager
                      Execute

T2 — Multi-Party Approval
─────────────────────────
Intent → Policy Engine → T2 → Approval Queue
                                    │
                   ┌────────────────┼────────────────┐
                   │                │                │
              Approver 1       Approver 2       Approver N
              (required)       (required)       (optional)
                   │                │                │
                   └────────────────┼────────────────┘
                                    │
                            All approved? ───No──→ Wait/Escalate
                                    │
                                   Yes
                                    │
                         Warrant Issued (strict TTL)
                                    │
                                 Execute

Timeout handling. If an approval is not acted on within the configured window, the system either escalates to a higher authority, notifies the organization admin, or auto-denies (configurable per policy). Default timeout: 1 hour for T1, 4 hours for T2.

Execution Warrants#

Execution warrants are the central innovation in Vienna OS. A warrant is a cryptographically signed, scope-constrained, time-limited authorization token. It is the only mechanism that authorizes execution. Without a valid warrant, no action executes. Period.

Warrants ≠ API keys. An API key authenticates an identity. A warrant authorizes a specific action with specific parameters within a specific time window. API keys are long-lived and broadly scoped. Warrants are ephemeral and surgically precise.
Warrant Structurejson
{
  "warrant_id": "wrt-4f6a8c0b-3e5f-7a9b-1c2d-e4f6a8c0b2d4",
  "intent_id": "int-2d4f6a8b-1c3e-5d7f-9a0b-c2d4e6f8a0b2",
  "scope": {
    "action": "send_email",
    "target": "smtp-gateway",
    "parameters": {
      "to": "customer@example.com",
      "subject": "Your support ticket #1234"
    }
  },
  "constraints": {
    "max_retries": 1,
    "max_recipients": 1,
    "allowed_domains": ["example.com"],
    "rollback_on_failure": true
  },
  "ttl": 300,
  "issued_at": "2026-03-25T21:35:01.000Z",
  "expires_at": "2026-03-25T21:40:01.000Z",
  "issuer": {
    "type": "operator",
    "id": "op-7f3a2b1c",
    "approval_id": "apr-6b8c0d1e"
  },
  "chain": {
    "parent_warrant": null,
    "depth": 0
  },
  "signature": "hmac-sha256:a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"
}

Scope enforcement. The warrant specifies exactly what action is permitted, against what target, with what parameters. The execution router checks the warrant scope before running any action. Parameter drift (e.g., changing the email recipient) invalidates the warrant.

Time-limited by design. Every warrant has a TTL measured in seconds. Once expired, the warrant is inert. There are no permanent warrants. Default TTL is 300 seconds (5 minutes) for T0, 600 seconds for T1, and 300 seconds for T2 (shorter because higher-risk actions should execute promptly or not at all).

Post-execution verification. After execution, the Verification Engine checks whether the actual operation matched the warrant scope. Did the email go to the authorized recipient? Did the database query touch only the permitted tables? Any mismatch generates an alert and is recorded in the audit trail.

Verification Engine#

The Verification Engine runs after every execution. It compares what was authorized (the warrant) with what actually happened (the execution result). This is the "trust but verify" layer.

Verification Flowtext
Execution Complete
       │
       ↓
┌─────────────────┐
│ Load Warrant    │ ← Original warrant scope and constraints
│ Load Result     │ ← Actual execution result and side effects
└────────┬────────┘
         │
         ↓
┌─────────────────┐
│ Scope Check     │ ← Did the action match the warrant scope?
│ Parameter Check │ ← Were parameters within constraints?
│ Target Check    │ ← Was the correct target affected?
│ Side Effect     │ ← Any unauthorized side effects?
│ Detection       │
└────────┬────────┘
         │
    ┌────┴────┐
    │         │
  Pass      Fail
    │         │
  Log to    Generate Alert
  Audit     Flag Agent
  Trail     Log to Audit Trail
            Revoke future warrants (optional)

Mismatch handling. When verification fails, the system can: (1) generate an alert to operators, (2) reduce the agent's trust score, (3) suspend the agent pending review, or (4) quarantine the execution result. The response is configurable per action type and severity.

Audit Trail#

The audit trail is an append-only, immutable log of every event in the governance pipeline. It is tamper-evident: each entry includes a hash chain linking it to the previous entry, making retroactive modification detectable.

What gets logged:

  • Intent submission (raw payload, source agent, timestamp)
  • Policy evaluation result (matched rule, tier assignment, deny reason)
  • Approval events (who approved/denied, when, with what context)
  • Warrant issuance (full warrant including scope, TTL, signature)
  • Execution start and completion (duration, result, errors)
  • Verification result (pass/fail, scope compliance details)
  • Agent trust score changes (before/after, reason)
  • System events (policy changes, agent registration, configuration updates)

Retention. Default retention is 90 days for standard entries, 7 years for compliance-flagged events (financial, legal, healthcare). Configurable per organization and action type.

Architecture

#

Vienna OS is a monolithic governance engine deployed as a single binary. Internally, it is composed of nine distinct services communicating via in-process function calls (no inter-service network hops in default deployment).

System Diagram#

Vienna OS — System Architecturetext
                        ┌──────────────────┐
                        │   Agent / Client  │
                        └────────┬─────────┘
                                 │
                                 ▼
                   ┌─────────────────────────┐
                   │     Intent Gateway       │
                   │  normalize · validate    │
                   │  deduplicate · enrich    │
                   └────────────┬────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │     Policy Engine        │
                   │  evaluate rules          │
                   │  assign risk tier        │
                   │  check rate limits       │
                   └────────────┬────────────┘
                                │
              ┌─────────────────┼─────────────────┐
              │                 │                 │
              ▼                 ▼                 ▼
       ┌────────────┐   ┌────────────┐   ┌────────────┐
       │  T0: Auto  │   │ T1: Single │   │ T2: Multi  │
       │  Approve   │   │  Approval  │   │  Approval  │
       └─────┬──────┘   └─────┬──────┘   └─────┬──────┘
              │                │                 │
              └─────────────────┼─────────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │    Warrant Authority     │
                   │  scope · ttl · sign      │
                   │  constraints · chain     │
                   └────────────┬────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │    Execution Router      │
                   │  warrant check · route   │
                   │  execute · capture       │
                   └────────────┬────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │   Verification Engine    │
                   │  scope compliance        │
                   │  parameter check         │
                   │  side effect detection   │
                   └────────────┬────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │      Audit Trail         │
                   │  append-only · hashed    │
                   │  tamper-evident · query  │
                   └─────────────────────────┘
                                │
                                ▼
                   ┌─────────────────────────┐
                   │      State Graph         │
                   │  SQLite / Postgres       │
                   │  persistent storage      │
                   └─────────────────────────┘

Data Flow#

A single intent traverses the full pipeline in milliseconds for T0 actions. Here is the data flow for each stage:

1
Ingress. Agent sends HTTP POST to /api/v1/agent/intent. Gateway parses, validates auth token, normalizes payload.
2
Enrichment. Gateway loads agent profile (trust score, history), attaches organizational context, timestamps.
3
Policy evaluation. Engine loads active rules sorted by priority. Evaluates conditions sequentially. First match determines outcome (allow + tier, deny, or escalate).
4
Approval routing. T0 bypasses queue. T1/T2 enters approval workflow with configured timeout and escalation.
5
Warrant issuance. Authority constructs warrant with scope, constraints, and TTL. Signs with HMAC-SHA256. Stores in state graph.
6
Execution. Router validates warrant (not expired, not revoked), routes to appropriate handler, captures result.
7
Verification. Engine compares execution result against warrant scope. Records compliance status.
8
Audit. Full pipeline trace written to append-only log with hash chain. Response returned to agent.

State Graph#

The State Graph is Vienna's persistence layer. It stores all entities and their relationships: agents, policies, warrants, executions, and audit entries. Default storage is SQLite (embedded, zero-config). Production deployments can use Postgres for horizontal scaling.

State Graph Schema (Simplified)text
┌─────────────┐     ┌──────────────┐     ┌───────────────┐
│   Agents    │────→│   Intents    │────→│   Warrants    │
│             │     │              │     │               │
│ id          │     │ id           │     │ id            │
│ name        │     │ agent_id     │     │ intent_id     │
│ trust_score │     │ action       │     │ scope         │
│ status      │     │ parameters   │     │ ttl           │
│ allowed_    │     │ risk_tier    │     │ constraints   │
│   actions   │     │ status       │     │ signature     │
└─────────────┘     └──────┬───────┘     └───────┬───────┘
                           │                     │
                           ▼                     ▼
                    ┌──────────────┐     ┌───────────────┐
                    │  Executions  │     │  Audit Trail  │
                    │              │     │               │
                    │ id           │     │ id            │
                    │ intent_id    │     │ type          │
                    │ warrant_id   │     │ entity_id     │
                    │ result       │     │ data          │
                    │ duration_ms  │     │ hash          │
                    │ verified     │     │ prev_hash     │
                    └──────────────┘     └───────────────┘

┌──────────────┐     ┌──────────────┐     ┌───────────────┐
│   Policies   │     │ Action Types │     │  Approvals    │
│              │     │              │     │               │
│ id           │     │ id           │     │ id            │
│ name         │     │ name         │     │ intent_id     │
│ priority     │     │ schema       │     │ approver_id   │
│ conditions   │     │ risk_tier    │     │ status        │
│ action       │     │ description  │     │ expires_at    │
└──────────────┘     └──────────────┘     └───────────────┘

Service Breakdown#

Vienna OS comprises nine internal services. In the default monolithic deployment, these are in-process modules. In a distributed deployment, they can be separated into independent services communicating over gRPC.

Intent Gateway
Request ingress, normalization, validation, deduplication, and context enrichment. Rate limiting and circuit breaking.
Policy Engine
Rule evaluation engine. Loads policies from state graph, evaluates conditions, assigns risk tiers, returns decisions.
Approval Manager
Manages approval queues, operator notifications, timeout handling, and escalation workflows.
Warrant Authority
Constructs, signs, and manages warrants. Handles scope definition, TTL computation, constraint encoding, and revocation.
Execution Router
Validates warrants, routes to action handlers, captures results, manages retries and rollbacks.
Verification Engine
Post-execution compliance check. Compares warrant scope to actual results. Generates alerts on mismatch.
Audit Service
Append-only log management. Hash chain computation, entry storage, query interface, retention enforcement.
Fleet Manager
Agent lifecycle management. Registration, trust scoring, suspension, activity tracking, and capability management.
State Graph
Persistence layer. SQLite (default) or Postgres. Manages all entity storage, relationships, and query optimization.

Deployment Topology#

Vienna OS supports three deployment models. All produce the same governance guarantees — the deployment model only affects scaling and operational complexity.

Single Binary
• All 9 services in one process
• SQLite embedded storage
• Zero external dependencies
• Ideal for: startups, dev, PoC
• Deploy: Docker, Fly.io, bare metal
Fly.io (Managed)
• Single machine, auto-restart
• Postgres via Fly Postgres
• TLS termination included
• Ideal for: teams, production
• Deploy: fly deploy
On-Premises
• Docker Compose or Kubernetes
• External Postgres required
• Full network isolation
• Ideal for: enterprise, regulated
• Deploy: Helm chart, Docker Compose

API Reference

#

All endpoints are prefixed with /api/v1. Authentication is required for all endpoints except /health and /api/v1/auth/login. Pass credentials as a Bearer token or session cookie.

All responses follow a consistent envelope: {"success": boolean, "data": ..., "error": ...}. Error responses include a machine-readable code and human-readable message.

Authentication#

Agent Intent#

The intent endpoints are the primary API surface for agent governance. Every agent action flows through these endpoints.

Policies#

Action Types#

Fleet Management#

Integrations#

Compliance#

Approvals#

Integration Guides

#

Vienna OS is runtime-agnostic. Any system that can make HTTP requests can integrate. These guides show how to wire governance into popular AI agent frameworks.

OpenClaw#

OpenClaw agents can integrate with Vienna OS by wrapping action execution in intent submissions. Every tool call routes through the governance pipeline.

openclaw-vienna-plugin.tstypescript
import { ViennaClient } from "./vienna-client";

const vienna = new ViennaClient({
  baseUrl: process.env.VIENNA_URL || "https://console.regulator.ai",
  apiKey: process.env.VIENNA_AGENT_KEY!,
  agentId: process.env.VIENNA_AGENT_ID!,
  tenantId: process.env.VIENNA_TENANT_ID!,
});

/**
 * Wrap any action in Vienna governance.
 * The action only executes if Vienna issues a warrant.
 */
async function governedAction(
  action: string,
  parameters: Record<string, unknown>,
  context?: Record<string, unknown>
) {
  // Submit intent to Vienna
  const intent = await vienna.submitIntent({
    action,
    parameters,
    context: {
      ...context,
      source_framework: "openclaw",
      timestamp: new Date().toISOString(),
    },
  });

  switch (intent.status) {
    case "executed":
      console.log(`✅ ${action} executed (warrant: ${intent.warrant.warrant_id})`);
      return intent.result;

    case "pending_approval":
      console.log(`⏳ ${action} awaiting approval (${intent.approval.approval_id})`);
      // Optionally wait for approval via webhook or polling
      return await vienna.waitForApproval(intent.approval.approval_id, {
        timeoutMs: 3600_000, // 1 hour
        pollIntervalMs: 5_000,
      });

    case "denied":
      throw new Error(`❌ ${action} denied: ${intent.reason}`);

    default:
      throw new Error(`Unexpected status: ${intent.status}`);
  }
}

// Usage in an OpenClaw agent
const result = await governedAction("send_email", {
  to: "customer@example.com",
  subject: "Your order has shipped",
  body: "Track your package at ...",
});

LangChain#

Wrap LangChain tools with a Vienna governance layer. The tool checks with Vienna before executing any action.

langchain_vienna.pypython
from langchain.tools import BaseTool
from typing import Optional, Type
from pydantic import BaseModel, Field
import requests
import os

VIENNA_URL = os.environ.get("VIENNA_URL", "https://console.regulator.ai")
VIENNA_KEY = os.environ["VIENNA_AGENT_KEY"]
AGENT_ID = os.environ["VIENNA_AGENT_ID"]
TENANT_ID = os.environ["VIENNA_TENANT_ID"]


class GovernedTool(BaseTool):
    """Base class for Vienna-governed LangChain tools.

    Subclass this instead of BaseTool. Your tool's _run method
    will only execute if Vienna issues a warrant.
    """

    vienna_action: str = ""  # Override in subclass

    def _call_vienna(self, parameters: dict) -> dict:
        """Submit intent to Vienna and handle the response."""
        response = requests.post(
            f"{VIENNA_URL}/api/v1/agent/intent",
            headers={
                "Content-Type": "application/json",
                "Authorization": f"Bearer {VIENNA_KEY}",
            },
            json={
                "action": self.vienna_action,
                "source": {"platform": "langchain", "agent_id": AGENT_ID},
                "tenant_id": TENANT_ID,
                "parameters": parameters,
            },
        )
        return response.json()["data"]

    def _run(self, **kwargs) -> str:
        # Check with Vienna first
        result = self._call_vienna(kwargs)

        if result["status"] == "denied":
            return f"Action denied by governance policy: {result['reason']}"

        if result["status"] == "pending_approval":
            return (
                f"Action requires approval (ID: {result['approval']['approval_id']}). "
                f"An operator must approve before execution."
            )

        # Warrant issued — proceed with actual execution
        return self._execute_with_warrant(result["warrant"], **kwargs)

    def _execute_with_warrant(self, warrant: dict, **kwargs) -> str:
        raise NotImplementedError("Override in subclass")


# Example: Governed email sender
class GovernedEmailTool(GovernedTool):
    name = "send_email"
    description = "Send an email (governed by Vienna OS)"
    vienna_action = "send_email"

    def _execute_with_warrant(self, warrant, **kwargs):
        # Your actual email sending logic here
        return f"Email sent (warrant: {warrant['warrant_id']})"


# Usage with LangChain agent
from langchain.agents import initialize_agent, AgentType
from langchain.llms import OpenAI

tools = [GovernedEmailTool()]
llm = OpenAI(temperature=0)
agent = initialize_agent(tools, llm, agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION)

CrewAI#

CrewAI tasks can be wrapped with Vienna governance using a callback pattern. The crew's task outputs are submitted as intents before being acted upon.

crewai_vienna.pypython
from crewai import Agent, Task, Crew
import requests, os

VIENNA_URL = os.environ.get("VIENNA_URL", "https://console.regulator.ai")
VIENNA_KEY = os.environ["VIENNA_AGENT_KEY"]

def governed_callback(output):
    """Submit task output to Vienna for governance before execution."""
    response = requests.post(
        f"{VIENNA_URL}/api/v1/agent/intent",
        headers={
            "Content-Type": "application/json",
            "Authorization": f"Bearer {VIENNA_KEY}",
        },
        json={
            "action": output.get("action", "task_execution"),
            "source": {"platform": "crewai", "agent_id": output.get("agent", "unknown")},
            "tenant_id": os.environ["VIENNA_TENANT_ID"],
            "parameters": output,
        },
    )
    result = response.json()
    if not result.get("success") or result["data"]["status"] == "denied":
        raise Exception(f"Governance denied: {result.get('error', 'Policy violation')}")
    return result["data"]

# Define agents and tasks
researcher = Agent(role="Researcher", goal="Find market data", backstory="...")
analyst = Agent(role="Analyst", goal="Analyze trends", backstory="...")

research_task = Task(
    description="Research Q1 market trends",
    agent=researcher,
    callback=governed_callback,  # Vienna checks before execution
)

crew = Crew(agents=[researcher, analyst], tasks=[research_task])
result = crew.kickoff()

Generic HTTP#

Any system that can make HTTP requests can integrate with Vienna OS. Here's the universal pattern.

curlbash
# Submit any agent action through governance
curl -X POST https://console.regulator.ai/api/v1/agent/intent \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VIENNA_AGENT_KEY" \
  -d '{
    "action": "your_custom_action",
    "source": {
      "platform": "your-framework",
      "agent_id": "your-agent-id"
    },
    "tenant_id": "your-tenant",
    "parameters": {
      "key": "value"
    }
  }'

# Response:
# {
#   "success": true,
#   "data": {
#     "intent_id": "int-abc123",
#     "status": "executed",
#     "execution_id": "exec-def456",
#     "warrant": { "warrant_id": "wrt-...", "scope": {...}, "ttl": 300 },
#     "audit_id": "aud-ghi789"
#   }
# }

Receiving Webhooks#

Vienna OS can send webhooks when governance events occur (approvals needed, actions executed, policy violations). Configure integrations via the console or API.

webhook-handler.tstypescript
import express from "express";
import crypto from "crypto";

const app = express();
app.use(express.json());

const WEBHOOK_SECRET = process.env.VIENNA_WEBHOOK_SECRET!;

// Verify HMAC-SHA256 signature
function verifySignature(payload: string, signature: string): boolean {
  const expected = crypto
    .createHmac("sha256", WEBHOOK_SECRET)
    .update(payload)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post("/webhooks/vienna", (req, res) => {
  const signature = req.headers["x-vienna-signature"] as string;
  const rawBody = JSON.stringify(req.body);

  if (!verifySignature(rawBody, signature)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const event = req.body;

  switch (event.type) {
    case "approval_required":
      console.log("Approval needed:", event.data.action_type);
      // Notify your team via Slack, email, etc.
      break;
    case "action_executed":
      console.log("Action completed:", event.data.execution_id);
      break;
    case "policy_violation":
      console.log("ALERT:", event.data.agent_id, event.data.message);
      break;
  }

  res.json({ received: true });
});

app.listen(3001);

Policy-as-Code Guide

#

Vienna OS policies are rules that automatically evaluate every agent intent. Rules are evaluated top-down by priority (highest first). First matching rule wins, like firewall rules.

Creating Rules#

Create policies via the API or the visual Policy Builder in the console.

Create a policy rulebash
curl -X POST https://console.regulator.ai/api/v1/policies \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VIENNA_API_KEY" \
  -d '{
    "name": "High-Value Transaction Gate",
    "description": "Require T2 multi-party approval for transactions over $10,000",
    "conditions": [
      { "field": "action_type", "operator": "equals", "value": "financial_transaction" },
      { "field": "amount", "operator": "gt", "value": 10000 }
    ],
    "action_on_match": "require_approval",
    "approval_tier": "T2",
    "priority": 100,
    "enabled": true
  }'

Condition Operators#

Vienna supports 14 condition operators. The available operators depend on the field type being evaluated.

OperatorDescriptionExample
equalsExact match{ field: "action_type", operator: "equals", value: "deploy" }
not_equalsNot equal{ field: "environment", operator: "not_equals", value: "production" }
containsString contains{ field: "action_type", operator: "contains", value: "delete" }
gtGreater than (numeric){ field: "amount", operator: "gt", value: 10000 }
gteGreater than or equal{ field: "risk_score", operator: "gte", value: 80 }
ltLess than{ field: "trust_score", operator: "lt", value: 50 }
lteLess than or equal{ field: "retry_count", operator: "lte", value: 3 }
inValue in array{ field: "agent_id", operator: "in", value: ["bot-a", "bot-b"] }
not_inValue not in array{ field: "environment", operator: "not_in", value: ["prod", "staging"] }
matchesRegex match{ field: "action_type", operator: "matches", value: "^deploy_.*" }
betweenNumeric range{ field: "amount", operator: "between", value: [1000, 50000] }
time_betweenTime-of-day range (HH:MM){ field: "time_of_day", operator: "time_between", value: ["18:00", "06:00"] }
existsField is present{ field: "parameters.override", operator: "exists", value: true }
not_existsField is absent{ field: "parameters.approval_bypass", operator: "not_exists", value: true }

Complex Examples#

Block after-hours financial transactions over $50Kjson
{
  "name": "After-Hours High-Value Block",
  "conditions": [
    { "field": "action_type", "operator": "equals", "value": "financial_transaction" },
    { "field": "amount", "operator": "gt", "value": 50000 },
    { "field": "time_of_day", "operator": "time_between", "value": ["18:00", "06:00"] }
  ],
  "action_on_match": "deny",
  "priority": 200
}
CTO approval for production database migrationsjson
{
  "name": "Prod DB Migration Gate",
  "conditions": [
    { "field": "action_type", "operator": "equals", "value": "database_migration" },
    { "field": "environment", "operator": "equals", "value": "production" }
  ],
  "action_on_match": "require_approval",
  "approval_tier": "T2",
  "required_approvers": ["operator-cto"],
  "priority": 150
}
Auto-approve reads from high-trust agentsjson
{
  "name": "Trusted Agent Auto-Approve",
  "conditions": [
    { "field": "action_type", "operator": "contains", "value": "read" },
    { "field": "trust_score", "operator": "gt", "value": 80 }
  ],
  "action_on_match": "allow",
  "priority": 50
}
Rate limit any single agentjson
{
  "name": "Agent Rate Limiter",
  "conditions": [
    { "field": "rate", "operator": "gt", "value": 100 }
  ],
  "action_on_match": "rate_limit",
  "priority": 300
}

Dry-Run Testing#

Test any intent against all active policies without executing it. The evaluate endpoint returns which rules matched and what action would be taken.

Test a hypothetical intentbash
curl -X POST https://console.regulator.ai/api/v1/policies/evaluate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $VIENNA_API_KEY" \
  -d '{
    "action_type": "financial_transaction",
    "amount": 75000,
    "agent_id": "billing-bot",
    "environment": "production",
    "time_of_day": "22:30"
  }'

# Response:
# {
#   "results": [
#     {
#       "rule_id": "...",
#       "rule_name": "After-Hours High-Value Block",
#       "matched": true,
#       "action": "deny",
#       "conditions_detail": [
#         { "field": "action_type", "passed": true },
#         { "field": "amount", "passed": true, "actual": 75000, "expected": "> 50000" },
#         { "field": "time_of_day", "passed": true, "actual": "22:30", "expected": "18:00-06:00" }
#       ]
#     }
#   ],
#   "final_action": "deny",
#   "matching_rule": "After-Hours High-Value Block"
# }

Industry Templates#

Vienna ships with pre-built policy templates for regulated industries. Import them via the API or the Policy Builder UI.

List available templatesbash
curl https://console.regulator.ai/api/v1/policies/templates \
  -H "Authorization: Bearer $VIENNA_API_KEY"

# Returns: financial_services, healthcare, devops, legal, general
# Each template contains 5-8 rules configured for that industry

Warrant Deep Dive

#

The execution warrant is Vienna OS's core innovation. This section explains why warrants exist, how they work, and why they're necessary for governing autonomous AI agents.

Problem Statement#

Traditional authorization (API keys, OAuth tokens, IAM roles) answers one question: “Who are you?” But for AI agents taking real-world actions, we need to answer a different question: “What exactly are you authorized to do, right now, this one time?”

An API key that authorizes “billing-bot” to “make payments” is dangerously broad. It doesn't constrain amount, recipient, timing, or frequency. If the agent is compromised or hallucinates, it can drain an account. Traditional auth is identity-based. Agent governance needs to be action-based.

The Warrant Model#

A Vienna execution warrant is a cryptographically signed, time-limited, scope-constrained authorization token. It authorizes exactly one action with specific parameters, issued only after policy evaluation and (optionally) operator approval.

Warrant structurejson
{
  "warrant_id": "wrt-7f3a2b1c-e8d4-4a9f-b2c1-9d8e7f6a5b4c",
  "scope": {
    "action": "wire_transfer",
    "target": "payments-service",
    "parameters": {
      "amount": 75000,
      "currency": "USD",
      "recipient": "vendor-456"
    }
  },
  "constraints": {
    "max_amount": 75000,
    "allowed_recipients": ["vendor-456"],
    "max_retries": 0,
    "rollback_on_failure": true
  },
  "ttl_seconds": 300,
  "issued_at": "2026-03-25T21:30:00Z",
  "expires_at": "2026-03-25T21:35:00Z",
  "issuer": {
    "type": "multi_party",
    "operators": ["operator-jane", "operator-mike"],
    "approval_id": "appr-abc123"
  },
  "chain_of_custody": {
    "intent_id": "int-xyz789",
    "policy_match": "high-value-transfer-gate",
    "risk_tier": "T2",
    "approval_time_ms": 45200
  },
  "signature": "hmac-sha256:a1b2c3d4e5f67890..."
}

Comparison with Traditional Auth#

PropertyAPI Key / OAuthVienna Warrant
AuthorizesIdentity (who you are)Specific action (what you can do)
ScopeBroad (all permitted actions)Narrow (one action, one time)
Time limitLong-lived (months/years)Seconds to minutes (TTL)
ParametersNoneAmount, recipient, target constrained
Post-execution checkNoneVerification Engine confirms compliance
Compromise impactFull access until revokedOne action, already expired
Audit chainWho authenticatedFull intent → policy → approval → execution chain
Tamper evidenceNoneHMAC-SHA256 signature

Warrant Lifecycle#

Warrant lifecycletext
1. INTENT    → Agent submits action request
2. EVALUATE  → Policy Engine checks against rules
3. TIER      → Risk tier assigned (T0/T1/T2)
4. APPROVE   → Operator(s) approve (if T1/T2)
5. ISSUE     → Warrant Authority creates signed warrant
                - Scope locked to exact parameters
                - TTL set (300s default, configurable)
                - Constraints attached (max amount, allowed targets)
                - HMAC-SHA256 signature computed
6. EXECUTE   → Execution Router validates warrant, runs action
7. VERIFY    → Verification Engine checks:
                - Did action match warrant scope?
                - Was amount within constraints?
                - Was target in allowed list?
                - Was execution within TTL?
8. ARCHIVE   → Warrant + verification result → immutable audit trail

Security Properties#

Vienna warrants provide five security guarantees:

  • Non-repudiation — Every warrant records who approved it and why. The chain of custody is immutable.
  • Scope enforcement — A warrant for $75,000 to vendor-456 cannot be used to send $750,000 to vendor-789.
  • Temporal constraint — Warrants expire. A 300-second TTL means the window for execution is minutes, not months.
  • Tamper evidence — HMAC-SHA256 signature means any modification to the warrant payload invalidates it.
  • Post-execution verification — Even if execution occurs, the Verification Engine confirms the action matched the warrant. Mismatches trigger alerts.

Implementation#

Warrants use HMAC-SHA256 with a server-side signing key. The signature covers the entire warrant payload (minus the signature field itself).

Warrant signing (server-side)typescript
import crypto from "crypto";

function signWarrant(warrant: Omit<Warrant, "signature">, signingKey: string): string {
  const payload = JSON.stringify(warrant, Object.keys(warrant).sort());
  return "hmac-sha256:" + crypto
    .createHmac("sha256", signingKey)
    .update(payload)
    .digest("hex");
}

function verifyWarrant(warrant: Warrant, signingKey: string): boolean {
  const { signature, ...payload } = warrant;
  const expected = signWarrant(payload, signingKey);
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

Industry Use Cases#

🏦

Financial Services

Wire transfer warrants constrain amount, recipient, currency. Multi-party T2 approval for high-value. 60-second TTL on execution. Post-verification confirms exact amount transferred.

🏥

Healthcare

PHI access warrants scope to specific patient ID and data fields. HIPAA-compliant audit trail. 30-second TTL. Verification confirms only authorized fields were accessed.

⚖️

Legal

Court filing warrants constrain to specific case number, document type, and filing deadline. Dual attorney-supervisor approval. Verification confirms correct court and case.

🚀

DevOps

Deploy warrants scope to specific service, environment, and version. Rollback constraints enabled. After-hours escalation. Verification confirms deployment target matched.

Security

#

Authentication#

Vienna OS supports three authentication mechanisms:

  • Session-based (operators) — Login with username/password, receive session cookie. Used by console UI.
  • API key (agents) — Bearer token in Authorization header. Scoped per agent with configurable permissions.
  • mTLS (enterprise) — Mutual TLS for agent identity verification. Certificate-based, no shared secrets.

Authorization#

Authorization in Vienna is two-layered: identity authorization (who can access the API) and action authorization (what they can do, enforced by warrants). Even an authenticated agent with valid API keys cannot execute an action without a warrant.

Encryption#

  • In transit — TLS 1.3 enforced on all connections
  • At rest — Database encryption via provider (Neon/RDS). Sensitive config fields encrypted with AES-256-GCM.
  • Warrant signatures — HMAC-SHA256 with rotating server-side keys

Audit Trail Integrity#

The audit trail is append-only. Entries cannot be modified or deleted. Each entry includes a hash of the previous entry, creating a tamper-evident chain (similar to blockchain but without consensus overhead). Any gap or modification in the chain is detectable.

Incident Response#

When Vienna detects a security event (signature mismatch, scope violation, unauthorized access attempt):

  1. Alert generated with severity level (info/warning/critical)
  2. Agent automatically suspended if critical
  3. Integration adapters notified (Slack, email, webhook)
  4. Full context captured in audit trail
  5. Operator review required to reactivate suspended agents

Compliance#

SOC 2 Type IIIn progress
HIPAA BAAAvailable on Enterprise
GDPRCompliant (EU deployment option)
EU AI ActDesigned for compliance
NIST AI RMFAligned
FedRAMPPlanned (2026 Q4)

Self-Hosting

#

Vienna OS can be self-hosted for teams that need on-premise deployment, air-gapped environments, or custom infrastructure.

Docker#

Docker deploymentbash
# Pull the image
docker pull ghcr.io/risk-ai/vienna-os:latest

# Run with environment variables
docker run -d \
  --name vienna-os \
  -p 8080:8080 \
  -e VIENNA_ENV=prod \
  -e VIENNA_SECRET_KEY=your-secret-key \
  -e POSTGRES_URL=postgresql://user:pass@host:5432/vienna \
  -e VIENNA_SIMULATION=false \
  ghcr.io/risk-ai/vienna-os:latest

# Verify
curl http://localhost:8080/health
# {"status":"ok"}

Environment Variables#

VariableRequiredDefaultDescription
VIENNA_SECRET_KEYYesServer signing key for warrants and sessions
POSTGRES_URLYesPostgreSQL connection string
VIENNA_ENVNoprodEnvironment: prod, staging, test
PORTNo8080Server listen port
VIENNA_SIMULATIONNotrueEnable simulation engine
VIENNA_LOG_LEVELNoinfoLogging level: debug, info, warn, error
VIENNA_CORS_ORIGINNo*Allowed CORS origins
VIENNA_SESSION_TTLNo86400Session TTL in seconds (24h)
VIENNA_WARRANT_TTLNo300Default warrant TTL in seconds (5min)
VIENNA_MAX_AGENTSNo100Maximum registered agents

PostgreSQL Setup#

Database setupbash
# Create database
createdb vienna

# Run migrations (auto-runs on first boot, or manually)
cd apps/console/server
for f in src/db/migrations/*.sql; do
  psql vienna < "$f"
done

Fly.io#

Fly.io deploymentbash
# Install flyctl
curl -L https://fly.io/install.sh | sh

# Launch (first time)
fly launch --name vienna-os --region iad

# Set secrets
fly secrets set VIENNA_SECRET_KEY=your-secret-key
fly secrets set POSTGRES_URL=your-connection-string

# Deploy
fly deploy

# Scale
fly scale count 2  # Run 2 instances for HA

Kubernetes#

kubernetes/deployment.yamlyaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vienna-os
  labels:
    app: vienna-os
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vienna-os
  template:
    metadata:
      labels:
        app: vienna-os
    spec:
      containers:
      - name: vienna-os
        image: ghcr.io/risk-ai/vienna-os:latest
        ports:
        - containerPort: 8080
        env:
        - name: VIENNA_SECRET_KEY
          valueFrom:
            secretKeyRef:
              name: vienna-secrets
              key: secret-key
        - name: POSTGRES_URL
          valueFrom:
            secretKeyRef:
              name: vienna-secrets
              key: postgres-url
        resources:
          requests:
            memory: "512Mi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "2"
        livenessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 10
          periodSeconds: 30
        readinessProbe:
          httpGet:
            path: /health
            port: 8080
          initialDelaySeconds: 5
          periodSeconds: 10
---
apiVersion: v1
kind: Service
metadata:
  name: vienna-os
spec:
  selector:
    app: vienna-os
  ports:
  - port: 80
    targetPort: 8080
  type: LoadBalancer

Ready to govern your agents?

Start with the free tier. No credit card required.