Skip to main content

Your First Governed Action

This guide walks through the complete governance lifecycle for an AI agent action.

Overview

Every action an AI agent takes flows through five stages:

  1. Submit — Agent calls evaluate_action()
  2. Score — ASCEND calculates risk using CVSS v3.1, NIST 800-30, and MITRE ATT&CK
  3. Decide — Auto-approve, queue for review, or deny based on your policies
  4. Review — Human approver acts on pending actions in the dashboard
  5. Execute — Agent proceeds only on approval

1. Submit an Action

Agent must be registered

Before submitting governed actions, your agent must be registered and activated in the Agent Registry. See Register Your Agent.

from ascend import AscendClient, FailMode, Decision

client = AscendClient(
api_key="owkai_your_key_here",
api_url="https://pilot.owkai.app",
agent_id="finance-bot",
agent_name="Finance Bot",
fail_mode=FailMode.CLOSED,
)

result = client.evaluate_action(
action_type="database_write",
resource="customer_financial_records",
resource_id="acct-12345",
context={
"environment": "production",
"data_sensitivity": "high_sensitivity",
"business_justification": "Customer requested account update",
},
wait_for_decision=False,
)

print(f"Decision: {result.decision}")
print(f"Risk Score: {result.risk_score}/100")
print(f"CVSS Score: {result.cvss_score}")
print(f"MITRE Tactic: {result.mitre_tactic}")
print(f"NIST Control: {result.nist_control}")

2. Understand the Risk Score

ASCEND scores every action using three industry frameworks:

FrameworkWhat It Evaluates
CVSS v3.1Attack vector, complexity, impact
NIST 800-30Threat likelihood, business impact
MITRE ATT&CKTactic and technique classification

The composite score (0-100) determines the decision:

Score RangeDecisionMeaning
Below auto-approve thresholdALLOWEDProceeds automatically
Between thresholdsPENDINGHuman review required
Above max thresholdDENIEDBlocked by policy

Thresholds are configured per agent in the Agent Registry.

3. Handle Each Decision

from ascend import Decision

if result.decision == Decision.ALLOWED:
# Proceed immediately
execute_database_write()

elif result.decision == Decision.PENDING:
# Wait for human approval
print(f"Queued for review. Action ID: {result.action_id}")

final = client.wait_for_decision(
action_id=result.action_id,
timeout=300,
poll_interval=5.0,
)

if final.decision == Decision.ALLOWED:
execute_database_write()
else:
print(f"Not approved: {final.reason}")

elif result.decision == Decision.DENIED:
# Blocked — do not proceed
print(f"Action denied: {result.reason}")
log_denial(result.action_id, result.reason)

4. Check Action Status

Poll the status of any action by its ID:

status = client.get_action_status(
action_id=result.action_id,
)
print(f"Current decision: {status.decision}")

5. MCP Server Governance

For agents using MCP servers, pass the server name to trigger Layer 13 enforcement:

result = client.evaluate_action(
action_type="tool_call",
resource="market_data",
mcp_server_name="bloomberg-mcp",
wait_for_decision=False,
)

print(result.mcp_governance["server_registered"])

Unregistered or deactivated MCP servers are denied with HTTP 403.

6. Model Registry Enforcement

For actions involving AI models, pass the model identifier to enforce compliance:

result = client.evaluate_action(
action_type="model_inference",
resource="underwriting_pipeline",
model_id="llama-3-fine-tuned",
wait_for_decision=False,
)

governance = result.model_governance
print(governance["compliance_status"])
# approved | partially_approved | denied

7. Error Handling

import time
from ascend.exceptions import (
AuthenticationError,
ConnectionError,
RateLimitError,
ValidationError,
TimeoutError,
)

try:
result = client.evaluate_action(
action_type="database_write",
resource="customer_db",
)
except AuthenticationError:
# Invalid or expired API key
raise
except ConnectionError:
# ASCEND unreachable — fail_mode applies
raise
except RateLimitError:
# Back off and retry
time.sleep(60)
except TimeoutError:
# Decision not reached within timeout
log_timeout(action_id)
except ValidationError as e:
# Invalid request parameters
print(f"Fix request: {e}")

8. Webhook Configuration

Receive real-time notifications instead of polling:

webhook = client.configure_webhook(
url="https://your-system.com/ascend/events",
events=["action.pending", "action.approved", "action.denied", "agent.blocked"],
secret="your_webhook_secret",
)
print(f"Webhook ID: {webhook.webhook_id}")

Next Steps