Safe Outputs Layer
Understand how AACWorkflow enforces policies and security checks on all agent-originated mutations.
The safe outputs layer is the security enforcement point where every change an agent makes — comments, patches, issue creation, status updates — is validated, checked for threats, and audited. It's the single choke point that ensures approval policies and threat detection are never bypassed.
Why a centralized enforcement layer
Without a central gate, every mutation path would need its own policy checks:
- Agent creates issue → check policy
- Agent comments → check policy
- Agent patches code → check policy
- etc.
This is brittle — it's easy to forget a check in one path. The safe outputs layer ensures all mutations go through one trusted applier.
How the safe outputs layer works
When an agent performs an action, it flows through:
- Normalize — canonicalize the action into a standard shape
- Policy check — evaluate workspace approval policies
- Threat scan — scan for security issues (secret leaks, prompt injection, etc.)
- Apply or queue — execute immediately (if allowed) or queue for approval
- Audit — record what happened in an immutable audit log
If any step flags an issue, the action is either rejected or queued for approval depending on severity.
Supported action types
The safe outputs layer handles these agent actions:
| Action | Example |
|---|---|
| Comment | Agent writes a comment on an issue |
| Patch | Agent creates a code patch |
| Pull request | Agent opens a PR |
| Status change | Agent marks an issue complete |
| Label change | Agent adds/removes labels |
| Issue creation | Agent opens a new issue |
| Assignment | Agent assigns an issue to someone |
Policy evaluation
When an agent attempts an action, the policy engine:
- Gathers all workspace policies that are enabled
- Matches policies based on action type and file paths
- Decides outcome:
- Allow — action proceeds immediately
- Require approval — action is queued, waiting for manual approval
- Deny — action is rejected outright
For example, if you have a policy:
Action type: patch
File glob: .github/workflows/**
Effect: require_approvalAny patch touching .github/workflows/ will be queued for approval.
See Approval policies for full details.
Threat detection
Before an action is applied, the threat detector scans for:
- Secret leaks — is the agent adding an API key or credential to code?
- Prompt injection — is there injected instruction attempts in comments?
- Dangerous patches — is the agent modifying sensitive files?
- Shell command risks — are there dangerous commands in scripts?
- Network risks — are there outbound connections to unknown hosts?
If threats are found:
- Info-level — logged but allowed
- Warn-level — allowed but flagged in audit
- Block-level — rejected or queued, depending on workspace policy
See Threat detection checks for full details.
Approval queuing
When an action requires approval:
- The action is stored with a cryptographic hash of its content
- An approval request appears in Inbox → Approvals
- An authorized approver (usually admin) reviews and decides
- On approval, the stored action is applied (hash verified to prevent tampering)
- On rejection, the agent is notified and the action is discarded
The hash ensures that the exact action that was queued is what gets applied — no tampering in between.
Audit trail
Every action is logged in the safe outputs audit trail:
- What happened — action type, outcome (applied/queued/rejected)
- Why — reasons from policy or threat detection
- When — timestamp
- Who — which agent, which task
- Evidence — hash of the action for traceability
View the audit trail in Settings → Audit Logs and filter by:
- Date range
- Agent
- Action type
- Outcome (applied, queued, rejected)
Use it to:
- Investigate security incidents
- Audit compliance
- Understand agent behavior
- Detect patterns (e.g., repeated rejections)
Distinguishing humans from agents
The safe outputs layer treats agent-originated actions differently from human-originated actions:
- Agent actions → evaluated against policies, threat detection, approval gates
- Human UI actions → not gated by policies (humans are trusted), but still audited
This means:
- You (a human) can always comment, update issues, etc.
- Agents must follow the approval policies you've set
- Everything is logged for audit
Redaction and privacy
All audit entries are redacted automatically:
- Secrets and API keys are masked
- Home directories are anonymized
- Sensitive file contents are not logged
This ensures audit logs are safe to share without accidentally exposing credentials.
Integration with policy and threat detection
The safe outputs layer is the integration point for:
- Approval policies (
approval-policies.md) — control when approval is required - Threat detection (
threat-detection-checks.md) — scan for security issues
Together, they form a comprehensive security framework:
- Policies define WHAT you want to control (e.g., "changes to .env are blocked")
- Threat detection finds HOW (e.g., "this patch adds an API key")
- Safe outputs layer ENFORCES it (ensuring both are checked)
Best practices
- Combine policies and detection — policies alone are insufficient (rely on manual config); threat detection alone can produce false positives. Use both.
- Review audit logs regularly — spot patterns and adjust policies
- Approve carefully — review queued actions thoroughly before approving
- Document your policies — help team members understand why certain actions require approval
- Test on non-production first — enable strict policies on a test workspace first, then roll out
Limitations
- Policies apply only to agents — human actions are audited but not gated
- Threat detection is heuristic — based on pattern matching, not foolproof
- Approval is manual — no automatic approval; a human must review
- Redaction is best-effort — custom secret patterns might not catch everything
Next steps
- Approval policies — define what requires approval
- Threat detection checks — scan for security issues
- Enterprise governance features — workspace-wide security