Terug naar hoofdpaneel

Centaur compliance-usecase

Handleiding voor organisaties die AI-agents willen inzetten zonder ze onbeperkt toegang te geven tot data, secrets, netwerken en interne workflows. De nadruk ligt op praktische beheersing: afschermen, beperken, loggen en beheren.

Self-hosted AI-agent runtime Kubernetes + Postgres Sandboxing iron-proxy Secrets buiten de sandbox

1. Samenvatting van de usecase

Centaur is relevant wanneer een organisatie AI-agents wil gebruiken voor echte taken, maar wel binnen duidelijke technische grenzen. Een agent mag bijvoorbeeld code lezen, een interne API raadplegen of een workflow uitvoeren, maar hij mag niet zomaar elk systeem benaderen, ruwe secrets uitlezen of zonder spoor acties uitvoeren.

De waarde zit dus niet in “AI-productiviteit” als losse belofte. De waarde zit in het gecontroleerd uitvoeren van agenttaken: een aparte sandbox per thread, netwerkverkeer via een proxy, credentials die buiten de sandbox blijven, en een event trail waarmee later onderzocht kan worden wat er is gebeurd.

Belangrijke nuance: Centaur is geen compliance-certificaat. Het levert technische controlepunten die kunnen helpen bij GDPR-, ISO 27001-, NEN 7510- of BIO-achtige eisen. De organisatie blijft zelf verantwoordelijk voor beleid, autorisaties, risicoanalyse, logging-retentie, DPIA’s, incidentprocedures en audits.

2. Toolset en verantwoordelijkheden

Onderdeel Rol in deze usecase Wie beheert dit?
Centaur API Ontvangt Slack/API-verzoeken, bewaart threads, runs en events, en coördineert sandbox-uitvoering. Platformteam / DevOps
Postgres Duurzame state: threads, agent turns, events, tool calls en execution status. Platformteam / databasebeheer
Kubernetes sandbox pods Elke agenttaak draait geïsoleerd in een eigen pod met beperkte containerrechten. Platformteam / clusterbeheer
NetworkPolicy Beperkt direct netwerkverkeer vanuit sandboxes. Sandbox pods praten alleen met de Centaur API en hun eigen proxy. Platformteam / security engineering
iron-proxy Controleert uitgaand verkeer en injecteert secrets pas aan de netwerkgrens. Platformteam / security engineering
Secret source Opslag van echte secrets, bijvoorbeeld Kubernetes Secrets of 1Password. Security / platformteam
Tool plugins Goedgekeurde acties die agents mogen uitvoeren, zoals interne API-calls of read-only databasevragen. Applicatieteam + platformteam
Slack/API ingress Gebruikersinterface en toegangspad naar de agent runtime. Platformteam + workspacebeheer

3. Architectuur in één beeld

De basisstroom is: gebruiker of systeem stuurt een verzoek, Centaur bewaart de run, start of hergebruikt een sandbox, de agent gebruikt alleen goedgekeurde tools, en uitgaand verkeer loopt via iron-proxy.

Slack of API client
→
Centaur API + Postgres
→
Kubernetes sandbox pod
Tool plugin
→
iron-proxy
→
Toegestane externe of interne API
Architectuurdiagram: Slack of API client naar Centaur API, Postgres, sandbox pod, tool plugin, iron-proxy en allowed API; een blocked host krijgt 403.
Architectuur-overzicht met toegestane en geblokkeerde egress via iron-proxy. Bestand: media/centaur-architecture-overview.svg

4. Implementatievoorbeeld

Een productie-installatie begint met een smalle scope. Kies eerst één workflow, één operator, één set tools, één secret source en één beperkt netwerkprofiel. Pas daarna breid je uit.

4.1 Operating boundary vastleggen

# Voorbeeld: minimale scope voor eerste productiepilot
operator: platform-team
gebruikersinterface: slack
slack_workspace: acme-prod
slack_channels:
  - ai-agent-pilot
repos:
  - acme/internal-tools
harnesses:
  - codex
tools:
  - warehouse-readonly
  - github-readonly
gevoelige_data:
  - klantdata
  - API credentials
  - interne incidentinformatie
review_required_for:
  - database writes
  - externe klantcommunicatie
  - productie-deployments

4.2 Infra secret maken

Centaur verwacht een bestaande Kubernetes Secret voor infrastructuurinstellingen. In de documentatie heet die standaard centaur-infra-env.

kubectl create namespace centaur-system

kubectl create secret generic centaur-infra-env \
  -n centaur-system \
  --from-literal=DATABASE_URL='postgres://centaur:REDACTED@postgres.example.com:5432/centaur' \
  --from-literal=IRON_MANAGEMENT_API_KEY='REDACTED_HIGH_ENTROPY_VALUE' \
  --from-literal=SANDBOX_SIGNING_KEY='REDACTED_HIGH_ENTROPY_VALUE' \
  --from-literal=SLACK_BOT_TOKEN='xoxb-REDACTED' \
  --from-literal=SLACK_SIGNING_SECRET='REDACTED' \
  --from-literal=SLACKBOT_API_KEY='REDACTED_HIGH_ENTROPY_VALUE'

4.3 Helm values voor productie

# values.production.yaml
secretManager:
  existingSecretName: centaur-infra-env
  envPrefix: ""

api:
  executionWorkerEnabled: true
  warmPoolEnabled: true

ironProxy:
  secretSource: onepassword-connect
  secretTtl: 10m

sandbox:
  image:
    repository: centaur-agent
    tag: latest
    pullPolicy: IfNotPresent
  runtimeClassName: gvisor

4.4 Installeren of upgraden

helm lint contrib/chart

helm upgrade --install centaur contrib/chart \
  --namespace centaur-system \
  --create-namespace \
  -f values.production.yaml

4.5 Smoke test

kubectl exec -n centaur-system deploy/centaur-centaur-api -- \
  curl -fsS http://localhost:8000/health

kubectl exec -n centaur-system deploy/centaur-centaur-api -- \
  curl -fsS http://localhost:8000/health/ready | jq

kubectl exec -n centaur-system deploy/centaur-centaur-api -- \
  curl -fsS http://localhost:8000/health/tools | jq

5. Secrets en egress-beheer

De belangrijkste security-keuze is dat echte credentials niet in de sandbox terechtkomen. Een tool of harness krijgt een placeholder. Pas wanneer de sandbox een toegestane request doet naar een toegestane host, vervangt iron-proxy die placeholder door de echte secret.

Let op: volgens de Centaur-documentatie is de standaard egress allowlist permissief. Voor een compliance-usecase moet je die expliciet beperken. Ook zijn secrets in de huidige beschrijving deployment-scoped; volledige per-user of per-channel scoping staat als roadmap beschreven.

5.1 Egress allowlist beperken

# Niet geschikt voor streng beheer:
transforms:
  - name: allowlist
    config:
      domains:
        - "*"
# Beter: alleen de hosts die echt nodig zijn
transforms:
  - name: allowlist
    config:
      domains:
        - "api.openai.com"
        - "api.github.com"
        - "github.com"
        - "warehouse.internal.example.com"

5.2 Secret binding in een tool

# tools/warehouse/pyproject.toml
[project]
name = "warehouse"
description = "Read-only internal warehouse queries"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = ["httpx>=0.27.0"]

[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"

[tool.centaur]
module = "client.py"
secrets = [
  {type = "http", name = "WAREHOUSE_API_KEY", match_headers = ["Authorization"], hosts = ["warehouse.internal.example.com"]},
]

5.3 Waarom dit helpt

Secret-bindingdiagram: sandbox agent gebruikt een placeholder, iron-proxy controleert host en header, haalt de echte secret uit de secret source en stuurt alleen naar de allowed API.
Secret-binding flow: de echte secret blijft buiten de sandbox. Bestand: media/centaur-secret-binding-flow.svg

6. Organisatie-tools toevoegen

Tools zijn Python-plugins die Centaur bij het opstarten ontdekt. Publieke methodes op de client worden als tool-methodes beschikbaar. Voor compliance is het verstandig om tools klein, expliciet en liefst eerst read-only te maken.

6.1 Voorbeeld: read-only warehouse tool

# tools/warehouse/client.py
import httpx
from centaur_sdk.tool_sdk import secret

class WarehouseClient:
    def query_customer_summary(self, customer_id: str) -> dict:
        """
        Haalt een beperkte klantensamenvatting op.
        Geen vrije SQL; alleen een gecontroleerde API-call.
        """
        token = secret("WAREHOUSE_API_KEY", "")
        response = httpx.post(
            "https://warehouse.internal.example.com/customer-summary",
            headers={"Authorization": f"Bearer {token}"},
            json={"customer_id": customer_id},
            timeout=30,
        )
        response.raise_for_status()
        return response.json()

def _client() -> WarehouseClient:
    return WarehouseClient()

6.2 Slecht patroon: te brede tool

# Vermijd dit als eerste compliance-tool:
def query(self, sql: str) -> dict:
    # De agent kan dan willekeurige SQL formuleren.
    # Dat maakt autorisatie, review en logging moeilijker.
    ...

6.3 Beter patroon: smalle methodes

# Beter beheerbaar:
def get_customer_summary(self, customer_id: str) -> dict: ...
def list_open_incidents(self, severity: str = "high") -> dict: ...
def get_invoice_status(self, invoice_id: str) -> dict: ...

6.4 Toolcontrole na deployment

kubectl exec -n centaur-system deploy/centaur-centaur-api -- \
  curl -fsS http://localhost:8000/health/tools | jq

7. Beheer, monitoring en audit

Centaur moet beheerd worden als platformcomponent. Het is geen losse chatbot. Leg daarom vast wie eigenaar is van secrets, images, policies, tools, logs, incidenten en upgrades.

7.1 Operationele checklist

7.2 Inspectie bij problemen

# Sandboxes bekijken
kubectl get pods -n centaur-system -l centaur.ai/managed=true

# API logs bekijken
kubectl logs -n centaur-system deploy/centaur-centaur-api --tail=200

# Health en toolstatus
kubectl exec -n centaur-system deploy/centaur-centaur-api -- \
  curl -fsS http://localhost:8000/health/tools | jq

7.3 Voorbeeld auditvragen

Vraag Waar kijk je?
Welke agenttaak heeft een tool aangeroepen? Postgres event trail: thread, run, tool call, final delivery.
Welke credentials zijn gebruikt? iron-proxy structured logs met secret-substitutie en transforms.
Heeft de agent een niet-toegestane host geprobeerd? iron-proxy logs; geweigerde requests horen 403 te krijgen.
Welke Slackgebruiker of API-client startte de run? Ingress logs, Centaur thread metadata en Slack event context.
Beheerloopdiagram: policy of tool wijziging naar deploy, smoke test, logs en audit, review en terug naar policy of tool wijziging.
Beheer- en auditloop voor doorlopende controle. Bestand: media/centaur-ops-audit-loop.svg

8. Voorstel voor diagrammen

De placeholders hierboven kunnen later vervangen worden door echte afbeeldingen. De snelste route is Mermaid of Graphviz, omdat je de diagrammen als tekst kunt beheren in Git.

8.1 Mermaid-voorbeeld voor architectuur

flowchart LR
  U[Slack/API client] --> A[Centaur API]
  A --> P[(Postgres)]
  A --> K[Kubernetes backend]
  K --> S[Sandbox pod]
  S --> T[Tool plugin]
  S --> X[iron-proxy]
  X --> V[Secret source]
  X --> H[Allowed host/API]
  X -. 403 .-> B[Blocked host]

8.2 Mermaid-voorbeeld voor secret-binding

sequenceDiagram
  participant Agent as Sandbox agent
  participant Proxy as iron-proxy
  participant Vault as Secret source
  participant API as Allowed API

  Agent->>Proxy: Request met placeholder WAREHOUSE_API_KEY
  Proxy->>Proxy: Controleer host + header
  Proxy->>Vault: Haal echte secret op
  Vault-->>Proxy: Secret value
  Proxy->>API: Request met echte Authorization header
  API-->>Proxy: Response
  Proxy-->>Agent: Response zonder secretwaarde

8.3 Excalidraw/diagrams.net

Voor een leesbare presentatiepagina is Excalidraw of diagrams.net handig. Gebruik dezelfde blokken, maar maak de proxy en secret source visueel opvallend. Dat zijn de belangrijkste onderdelen voor de compliance-usecase.

9. Bronnen