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:
- Submit — Agent calls
evaluate_action() - Score — ASCEND calculates risk using CVSS v3.1, NIST 800-30, and MITRE ATT&CK
- Decide — Auto-approve, queue for review, or deny based on your policies
- Review — Human approver acts on pending actions in the dashboard
- Execute — Agent proceeds only on approval
1. Submit an Action
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:
| Framework | What It Evaluates |
|---|---|
| CVSS v3.1 | Attack vector, complexity, impact |
| NIST 800-30 | Threat likelihood, business impact |
| MITRE ATT&CK | Tactic and technique classification |
The composite score (0-100) determines the decision:
| Score Range | Decision | Meaning |
|---|---|---|
| Below auto-approve threshold | ALLOWED | Proceeds automatically |
| Between thresholds | PENDING | Human review required |
| Above max threshold | DENIED | Blocked 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
- SDK Reference — full method reference
- Agent Registry — configure agent thresholds
- Approval Workflows — multi-stage approvals
- Kill Switch — block agents in real time