Erste Schritte

Schnelleinstieg

In etwa 30 Minuten von der Anmeldung zu aufgezeichneten Entscheidungen allow, warn, require_approval und block, einer Genehmigung im Decision Desk und einem versiegelten Nachweispaket.

10 Min. Lesezeit2329 Wörter

Diese Anleitung führt einen Entwicklerarbeitsplatz von der Anmeldung zu je einer aufgezeichneten Entscheidung pro Richtlinienergebnis: allow, warn, require_approval und block. Sie registrieren einen KYC-Onboarding-Agenten und sein Tool, veröffentlichen eine KYC-Startrichtlinie, rufen sie mit einem API-Schlüssel des Tenants aus dem Governance-SDK auf, lassen eine zweite Person den Fall require_approval im Decision Desk entscheiden und finden jede Entscheidung im Audit Trail. Die Befehle richten sich an die KLA-Entwicklungsumgebung unter https://api.dev.kla.digital. Planen Sie etwa 30 Minuten ein.

Sie brauchen zwei Personen im Tenant: Sie selbst als Tenant-Administrator, der Richtlinien erstellt, und eine prüfende Person mit der Rolle kla:approver. KLA lehnt eine Prüfung oder Genehmigung durch die Person ab, die die Anfrage gestellt hat.


KLA-CLI ausführen

Die KLA-CLI läuft derzeit aus diesem Monorepo. Bauen Sie sie im Stammverzeichnis des Repositorys mit Node.js 20.x:

pnpm install --frozen-lockfile
pnpm kla --help
alias kla='pnpm --silent kla'

Der Repository-Wrapper baut die CLI neu, wenn eine Quelldatei neuer ist als die erzeugte Ausgabe. Die folgenden Schritte verwenden außerdem jq.


Schritt 1: Anmelden

Legen Sie einen CLI-Kontext für Ihren Tenant an und melden Sie sich im Browser an. Die CLI nutzt den öffentlichen Client kla-cli mit PKCE und speichert kein Client-Secret.

export KLA_TENANT_ID='<tenant external ID>'
kla context set "$KLA_TENANT_ID" \
  --api-url https://api.dev.kla.digital \
  --tenant "$KLA_TENANT_ID" \
  --issuer "https://auth.dev.kla.digital/realms/$KLA_TENANT_ID" \
  --client-id kla-cli \
  --use
kla auth login
kla auth test

kla auth test zeigt den Tenant, dem Ihre Anmeldedaten zugeordnet sind. Die prüfende Person führt dieselben Befehle in ihrem eigenen Terminal aus und meldet sich mit ihrem eigenen Konto an. Siehe Authentifizierung.


Schritt 2: Agent und Tool registrieren

Schreiben Sie ein Agentenmanifest. governanceIntent.environment legt fest, wo der Agent kontrolliert wird: development, staging oder production.

cat > kyc-agent.yaml <<'YAML'
name: KYC Onboarding Agent
description: Screens retail account applications and recommends an onboarding decision.
model:
  provider: openai
  name: gpt-4o
pipeline:
  - type: llm_generate
    name: screen_application
    config:
      template: Review the application and recommend approve, review, or decline with reasons.
owners:
  - email: [email protected]
tools:
  - open_customer_account
humanOversightRequired: true
governanceIntent:
  environment: development
YAML

kla agent create --file kyc-agent.yaml > agent.json
export AGENT_ID=$(jq -r '.id' agent.json)

Eine Richtlinie, die auf diesen Agenten beschränkt ist (scope.agentIds), kann nur zur Prüfung eingereicht werden, wenn ihr scope.environments dieselbe Umgebung nennt. Legen Sie governanceIntent bei der Registrierung fest: Ein späterer Draft kann es nicht ändern.

KLA entscheidet nur über Tools, die im Tool Catalog des Tenants stehen. Registrieren Sie das Tool, das der Agent aufruft, mit den Feldern, die die Richtlinie liest:

cat > open-customer-account.tool.json <<'JSON'
{
  "key": "open_customer_account",
  "name": "Open customer account",
  "description": "Opens a retail account after KYC screening.",
  "risk_class": "high",
  "input_schema": {
    "type": "object",
    "properties": {
      "sanctions_hit": { "type": "boolean" },
      "pep_match": { "type": "boolean" },
      "country_risk": { "type": "string", "enum": ["standard", "high"] },
      "risk_score": { "type": "number", "minimum": 0, "maximum": 100 }
    },
    "required": ["sanctions_hit", "pep_match", "country_risk", "risk_score"]
  }
}
JSON

kla api tools create --input @open-customer-account.tool.json

Hat der Tenant das Tool bereits, antwortet tools.create mit CONFLICT, und der vorhandene Eintrag bleibt bestehen.


Schritt 3: Richtlinie schreiben und vier Ergebnisse simulieren

Richtlinienregeln lesen Tool-Argumente unter context.action.toolArgs.<field>. Agent-Ingress stellt action.parameters unter demselben Pfad bereit. Validierte Eingaben unterstützen außerdem tool.<toolId>.input.<field>.

Die KYC-Startrichtlinie lehnt einen Sanktionstreffer ab, leitet eine politisch exponierte Person (PEP) oder ein Hochrisikoland an eine zweite Person weiter, markiert mittleres Risiko und eröffnet Konten mit niedrigem Risiko. Jede andere Anfrage, etwa ein Risikowert über 70 oder ein fehlendes Feld, führt zur Standardentscheidung block.

cat > kyc-onboarding-gate.template.json <<'JSON'
{
  "policyId": "kyc-onboarding-gate",
  "name": "KYC onboarding gate",
  "description": "Opens low-risk accounts, flags medium risk, sends PEP and high-risk countries to a second person, and refuses sanctions hits.",
  "version": "1.0.0",
  "scope": { "tools": [], "environments": ["development"], "agentIds": ["AGENT_ID"] },
  "defaultDecision": "block",
  "rules": [
    {
      "ruleId": "block-sanctions-hit",
      "name": "Refuse a sanctions hit",
      "interceptionPoint": "tool_call",
      "when": { "expression": { "and": [
        { "==": [{ "var": "context.action.toolName" }, "open_customer_account"] },
        { "==": [{ "var": "context.action.toolArgs.sanctions_hit" }, true] }
      ] } },
      "then": {
        "decision": "block",
        "reason": "Sanctions screening returned a hit.",
        "reasonCodes": ["sanctions_hit"],
        "remediation": { "summary": "Refuse the account and follow the sanctions procedure.", "steps": [] }
      },
      "execution": { "mode": "deterministic" },
      "evidence": { "artifactRefs": [], "evaluatedFields": [
        "context.action.toolName", "context.action.toolArgs.sanctions_hit"
      ] }
    },
    {
      "ruleId": "review-pep-or-high-risk-country",
      "name": "Second review for a PEP or a high-risk country",
      "interceptionPoint": "tool_call",
      "when": { "expression": { "and": [
        { "==": [{ "var": "context.action.toolName" }, "open_customer_account"] },
        { "==": [{ "var": "context.action.toolArgs.sanctions_hit" }, false] },
        { "or": [
          { "==": [{ "var": "context.action.toolArgs.pep_match" }, true] },
          { "==": [{ "var": "context.action.toolArgs.country_risk" }, "high"] }
        ] }
      ] } },
      "then": {
        "decision": "require_approval",
        "reason": "A PEP match or a high-risk country needs a second person.",
        "reasonCodes": ["pep_or_high_risk_country"],
        "approverGroup": "kla:approver",
        "remediation": { "summary": "Approve or reject the account in the Decision Desk.", "steps": [] }
      },
      "execution": { "mode": "deterministic" },
      "evidence": { "artifactRefs": [], "evaluatedFields": [
        "context.action.toolName", "context.action.toolArgs.sanctions_hit",
        "context.action.toolArgs.pep_match", "context.action.toolArgs.country_risk"
      ] }
    },
    {
      "ruleId": "warn-medium-risk",
      "name": "Flag medium risk",
      "interceptionPoint": "tool_call",
      "when": { "expression": { "and": [
        { "==": [{ "var": "context.action.toolName" }, "open_customer_account"] },
        { "==": [{ "var": "context.action.toolArgs.sanctions_hit" }, false] },
        { "==": [{ "var": "context.action.toolArgs.pep_match" }, false] },
        { "==": [{ "var": "context.action.toolArgs.country_risk" }, "standard"] },
        { ">": [{ "var": "context.action.toolArgs.risk_score" }, 30] },
        { "<=": [{ "var": "context.action.toolArgs.risk_score" }, 70] }
      ] } },
      "then": {
        "decision": "warn",
        "reason": "Medium customer risk: open the account and schedule enhanced monitoring.",
        "reasonCodes": ["medium_risk"],
        "remediation": { "summary": "Schedule enhanced monitoring for this customer.", "steps": [] }
      },
      "execution": { "mode": "deterministic" },
      "evidence": { "artifactRefs": [], "evaluatedFields": [
        "context.action.toolName", "context.action.toolArgs.sanctions_hit",
        "context.action.toolArgs.pep_match", "context.action.toolArgs.country_risk",
        "context.action.toolArgs.risk_score"
      ] }
    },
    {
      "ruleId": "allow-low-risk",
      "name": "Open a low-risk account",
      "interceptionPoint": "tool_call",
      "when": { "expression": { "and": [
        { "==": [{ "var": "context.action.toolName" }, "open_customer_account"] },
        { "==": [{ "var": "context.action.toolArgs.sanctions_hit" }, false] },
        { "==": [{ "var": "context.action.toolArgs.pep_match" }, false] },
        { "==": [{ "var": "context.action.toolArgs.country_risk" }, "standard"] },
        { ">=": [{ "var": "context.action.toolArgs.risk_score" }, 0] },
        { "<=": [{ "var": "context.action.toolArgs.risk_score" }, 30] }
      ] } },
      "then": {
        "decision": "allow",
        "reason": "Low customer risk with clear screening.",
        "reasonCodes": ["low_risk"]
      },
      "execution": { "mode": "deterministic" },
      "evidence": { "artifactRefs": [], "evaluatedFields": [
        "context.action.toolName", "context.action.toolArgs.sanctions_hit",
        "context.action.toolArgs.pep_match", "context.action.toolArgs.country_risk",
        "context.action.toolArgs.risk_score"
      ] }
    },
    {
      "ruleId": "allow-account-opening-result",
      "name": "Return the authorized account-opening result",
      "interceptionPoint": "tool_result",
      "appliesTo": { "toolKeys": ["open_customer_account"] },
      "when": { "expression": { "==": [{ "var": "context.action.toolName" }, "open_customer_account"] } },
      "then": { "decision": "allow", "reason": "The authorized account-opening result can be returned.", "reasonCodes": ["account_opening_result"] },
      "execution": { "mode": "deterministic" }
    }
  ]
}
JSON

export POLICY_ID='kyc-onboarding-gate'
jq --arg agent "$AGENT_ID" --arg policy "$POLICY_ID" \
  '.policyId = $policy | .scope.agentIds = [$agent]' \
  kyc-onboarding-gate.template.json > kyc-onboarding-gate.json
kla policy registry create --file kyc-onboarding-gate.json | jq '.lint'

lint.ok ist true. lint.issues enthält eine POLICY_BAND_GAP-Warnung für Werte über 70. Prüfen Sie die Lint-Ergebnisse und die Standardentscheidung block der Richtlinie, bevor Sie den Entwurf zur Prüfung einreichen. POLICY_ID muss im Tenant neu sein; findet kla policy registry get "$POLICY_ID" bereits eine Richtlinie, wählen Sie eine andere ID.

Simulieren Sie einen Antrag pro Ergebnis. Eine Simulation wertet den Draft aus, ohne eine Live-Entscheidung aufzuzeichnen, und die Prüfung setzt eine gespeicherte Simulation genau dieses Drafts voraus:

simulate() {
  jq -n --arg tenant "$KLA_TENANT_ID" --arg agent "$AGENT_ID" --argjson args "$2" '{
    context: {
      occurredAt: (now | todate),
      identifiers: { workspaceId: $tenant, agentId: $agent, environment: "development" },
      action: { actionType: "tool_call", toolName: "open_customer_account", toolArgs: $args }
    }
  }' > "simulate-$1.json"
  kla policy registry simulate "$POLICY_ID" 1.0.0 --input "@simulate-$1.json" \
    | jq -c '{case: "'"$1"'", decision: .decision.decision, rule: .decision.primaryBasis.ruleId}'
}
simulate low '{"sanctions_hit":false,"pep_match":false,"country_risk":"standard","risk_score":15}'
simulate medium '{"sanctions_hit":false,"pep_match":false,"country_risk":"standard","risk_score":55}'
simulate pep '{"sanctions_hit":false,"pep_match":true,"country_risk":"standard","risk_score":20}'
simulate sanctions '{"sanctions_hit":true,"pep_match":false,"country_risk":"standard","risk_score":10}'
{"case":"low","decision":"allow","rule":"allow-low-risk"}
{"case":"medium","decision":"warn","rule":"warn-medium-risk"}
{"case":"pep","decision":"require_approval","rule":"review-pep-or-high-risk-country"}
{"case":"sanctions","decision":"block","rule":"block-sanctions-hit"}

Reichen Sie den Draft zur Prüfung ein:

kla policy registry submit-review "$POLICY_ID" 1.0.0 --comment 'Starter KYC onboarding gate.'

Schritt 4: Richtlinie prüfen und veröffentlichen

Die prüfende Person genehmigt die Version in ihrem eigenen Terminal:

kla policy registry review kyc-onboarding-gate 1.0.0 \
  --decision approve --comment 'Four outcomes match the KYC procedure.' --yes

Sie veröffentlichen sie. Die Veröffentlichung beginnt sofort, sofern Sie kein --effective-from angeben, und öffnet eine Decision Request für die prüfende Person:

kla policy registry publish "$POLICY_ID" 1.0.0 --reason 'First KYC onboarding gate.' --yes

Die prüfende Person öffnet Decision Desk in der Console unter https://kla.digital, öffnet Publish KYC onboarding gate 1.0.0?, öffnet Policy version diff und Lint report, wählt Approve publish, gibt einen Grund an und wählt Record decision. Danach ist die Version veröffentlicht.


Schritt 5: API-Schlüssel für den Agenten erstellen

Der Agent authentifiziert sich mit einem API-Schlüssel des Tenants. Ein Schlüssel mit dem Scope policy:evaluate kann Entscheidungen anfordern und sonst nichts:

kla api secrets createApiKey \
  --input '{"name":"kyc-onboarding-agent","permissions":["policy:evaluate"],"expiresAt":"2027-01-08"}' \
  > api-key.json
export KLA_API_KEY=$(jq -r '.key' api-key.json)
jq '.effectiveAccess' api-key.json

KLA gibt den Schlüssel einmal zurück. Legen Sie ihn in Ihrem Secret-Manager ab, behalten Sie apiKey.id für den Widerruf und löschen Sie api-key.json. Ein Tenant-Administrator kann den Schlüssel auch unter Settings > API keys erstellen.


Schritt 6: Entscheidungen über das Governance-SDK anfordern

Das Governance-SDK fragt KLA nach einer Entscheidung, bevor der Agent ein Tool aufruft. KLA zeichnet jede Entscheidung unter Ihren Run- und Gate-Kennungen auf und führt nichts aus; der Agent handelt nach dem Ergebnis. Eine Entscheidung require_approval öffnet eine Decision Request im Decision Desk.

Erstellen Sie die Identitätsdatei einmal für diese Aktionen und bewahren Sie sie für Wiederholungen auf. Beide Beispiele lesen den ursprünglichen Zeitstempel und verwenden getrennte Run-Kennungen für Python und Node.js. Verwenden Sie für neue Aktionen eine neue Datei.

if [ ! -f kyc-action-identity.env ]; then
  printf 'export KLA_ACTION_BATCH_ID=%s\nexport KLA_ACTION_OCCURRED_AT=%s\n' \
    "$(node -e "console.log(require('node:crypto').randomUUID())")" \
    "$(date -u +'%Y-%m-%dT%H:%M:%SZ')" > kyc-action-identity.env
fi
. ./kyc-action-identity.env

Python

pip install kla-governance
import os
from kla_governance import PolicyClient

client = PolicyClient(
    base_url="https://api.dev.kla.digital",
    workspace_id=os.environ["KLA_TENANT_ID"],
    api_key=os.environ["KLA_API_KEY"],
)

applications = {
    "case-1001": {"sanctions_hit": False, "pep_match": False, "country_risk": "standard", "risk_score": 15},
    "case-1002": {"sanctions_hit": False, "pep_match": False, "country_risk": "standard", "risk_score": 55},
    "case-1003": {"sanctions_hit": False, "pep_match": True, "country_risk": "standard", "risk_score": 20},
    "case-1004": {"sanctions_hit": True, "pep_match": False, "country_risk": "standard", "risk_score": 10},
}

for case_id, fields in applications.items():
    result = client.evaluate_tool_call(
        run_id=f"{case_id}-python-{os.environ['KLA_ACTION_BATCH_ID']}",
        occurred_at=os.environ["KLA_ACTION_OCCURRED_AT"],
        gate_id="open-account",
        tool_name="open_customer_account",
        tool_args=fields,
        agent_id=os.environ["AGENT_ID"],
        environment="development",
        policy_id=os.environ["POLICY_ID"],
    )
    print(case_id, result.decision, result.rule_id, result.approval.approval_id if result.approval else "")

Node.js

npm install @kla-digital/governance
import { KLAPolicyClient } from '@kla-digital/governance';

const client = new KLAPolicyClient({
  baseUrl: 'https://api.dev.kla.digital',
  workspaceId: process.env.KLA_TENANT_ID!,
  apiKey: process.env.KLA_API_KEY!,
});

const applications = {
  'case-1001': { sanctions_hit: false, pep_match: false, country_risk: 'standard', risk_score: 15 },
  'case-1002': { sanctions_hit: false, pep_match: false, country_risk: 'standard', risk_score: 55 },
  'case-1003': { sanctions_hit: false, pep_match: true, country_risk: 'standard', risk_score: 20 },
  'case-1004': { sanctions_hit: true, pep_match: false, country_risk: 'standard', risk_score: 10 },
};

for (const [caseId, toolArgs] of Object.entries(applications)) {
  const result = await client.evaluateToolCall({
    runId: `${caseId}-node-${process.env.KLA_ACTION_BATCH_ID}`,
    occurredAt: process.env.KLA_ACTION_OCCURRED_AT!,
    gateId: 'open-account',
    toolName: 'open_customer_account',
    toolArgs,
    caseReference: caseId,
    agentId: process.env.AGENT_ID,
    environment: 'development',
    policyId: process.env.POLICY_ID,
  });
  console.log(caseId, result.decision, result.ruleId, result.approval?.approvalId ?? '');
}

Beide Programme geben eine Entscheidung pro Antrag aus:

case-1001 allow allow-low-risk
case-1002 warn warn-medium-risk
case-1003 require_approval review-pep-or-high-risk-country <Decision Request ID>
case-1004 block block-sanctions-hit

Eine Wiederholung derselben Aktion erfordert die ursprünglichen Werte für runId, gateId, occurredAt, Tool-Argumente, Agent, Richtlinie und Umgebung. Bei automatischen Wiederholungen behält das SDK den Inhalt bei. Ein separater SDK-Aufruf ohne expliziten Zeitstempel erzeugt ein neues occurredAt; dieselben Run- und Gate-Kennungen führen dann zu 409. Bewahren Sie kyc-action-identity.env und die ursprünglichen Eingaben auf, um diese Beispiele erneut auszuführen. Jede eigenständige Aktion in einem Run erhält eine neue gateId. Ein identischer Inhalt liefert die aufgezeichnete Entscheidung. Ein 403 mit api_key_scope_denied bedeutet, dass dem Schlüssel der Scope policy:evaluate fehlt.


Schritt 7: Die Prüfung im Decision Desk entscheiden

Die prüfende Person öffnet Decision Desk, öffnet die Anfrage für case-1003, wählt Approve decision oder Reject decision, gibt einen Grund an, bestätigt und wählt Record decision. KLA zeichnet die Entscheidung bei der Anfrage und im Audit Trail auf.

In dieser Anleitung stoppt der Agent bei require_approval und eröffnet das Konto nicht. Dieselbe Anfrage erneut zu senden liefert die aufgezeichnete Entscheidung require_approval. Für einen Agenten, der auf die prüfende Person wartet und dann fortfährt, verwenden Sie den Action Ingress im letzten Abschnitt dieser Seite.


Schritt 8: Entscheidungen im Audit Trail finden

Öffnen Sie Audit Trail in der Console und suchen Sie nach case-1003. Die aufgezeichnete Abfolge zeigt die Richtlinienentscheidung mit dem API-Schlüssel als Akteur, die Decision Request und die Entscheidung der prüfenden Person, jeweils mit Eintrags-Prüfsumme und Proof-Root.


Schritt 9: Ein versiegeltes Nachweispaket exportieren

Exportieren Sie kontrollierte Entscheidungen, Genehmigungen und Audit-Einträge mit der kla-CLI. Das Paket ist signiert und listet den Hash jeder enthaltenen Datei.

# Export the last 30 days to a local directory
kla evidence export --tenant $KLA_TENANT_ID --days 30 --out ./evidence

# Export an exact time window
kla evidence export --tenant $KLA_TENANT_ID \
  --start-date 2026-07-01 \
  --end-date 2026-07-31 \
  --out ./evidence

Prüfen Sie das Paket offline, bevor Sie es an eine Prüferin oder einen Prüfer übergeben:

kla evidence verify ./evidence/<bundle file>.zip

Weiter: KLA das Tool ausführen lassen

In dieser Anleitung führt der Agent sein Tool nach jeder Entscheidung selbst aus. Damit KLA das Tool über einen registrierten Connector ausführt, sendet der Agent jede Aktion mit KLAClient und einem API-Schlüssel mit dem Scope actions:propose an POST /v1/agent-actions. Dieser Weg erfordert ein genehmigtes, bereitgestelltes Release und ein aktives Mandat, das die Tools, Operationen, Ziele und Zwecke festlegt, für die der Agent handeln darf:

PRODUCTION_AGENT_ID='<registered production Agent UUID>'
kla agent mandate create "$PRODUCTION_AGENT_ID" --file mandate.yaml
kla agent mandate submit <mandate ID>
kla agent mandate get <mandate ID>
kla agent mandate approve <mandate ID> --version <version> --reason 'Scope matches the onboarding procedure.'
kla agent mandate activate <mandate ID>

Dieser Quickstart hat einen Entwicklungs-Agent registriert. Ein Production-Release benötigt einen separaten Agent mit governanceIntent.environment: production und eine veröffentlichte, auf production begrenzte Richtlinie, die diesen Agent zulässt. Einen Agent durchgängig steuern zeigt diese Registrierung und den Release-Ablauf. Die Entwicklungsregistrierung bleibt bestehen. Verwenden Sie für das Mandat die ID des Production-Agents; eine andere Person genehmigt die genaue von get zurückgegebene Version. Governance-SDK-Schnelleinstieg (Python) behandelt die Mandatsdatei und die erste kontrollierte Aktion.

Schnelleinstieg | Developer Docs | KLA Control Plane