How Conduct works
Conduct is a governed automation layer for AI agents. You install a playbook, configure it once, and it turns tickets, PRs, alerts, and incidents into repeatable workflows, triggered by a webhook, on a schedule, or on demand. Every run is traced, every outcome is recorded.
Playbook
A YAML file that defines what an agent does, its blocks (AI reasoning, tool calls, approval gates), its triggers, and its inputs. Playbooks live in the Conduct registry and can be customized.
Each block is typed: brain (LLM reasoning), tool_call (GitHub, Slack, Linear), approval (human gate), or condition (branching logic). The graph is editable on the canvas.
Install
Installing a playbook creates a workflow in your workspace. Conduct generates the agent graph, registers any GitHub webhooks, and stores the resolved inputs. No code to write.
Under the hood: a WorkflowVersion record is created from the playbook YAML. The YAML is interpreted at install time, the canvas shows the live graph.
Configure
Assign an environment to the agent. An environment holds your credentials (GitHub PAT, Slack token, Linear key, LLM API key). One environment can be shared across many agents.
Credentials are encrypted with AES-256-GCM before storage. They are decrypted in-process at runtime, scoped to the agent's workspace, and never returned to the client.
Run
A run is created by a trigger: a GitHub webhook (pull_request, issues), a schedule (cron), a manual click in the UI, or a POST to the API. Runs execute the graph block by block.
The executor advances one block at a time. If a block hits an approval gate, the run is paused and waits for a human decision before proceeding.
Trace
Every run streams live events: block_started, brain_tool_call, block_completed, run_paused. The run detail page shows the full trace in real time via Server-Sent Events.
Events are written to run_events and are immutable. You can replay any run's trace after the fact, nothing is discarded.
Outcome
When a run completes, Conduct writes a semantic outcome: pr_opened, review_completed, issue_triaged, incident_investigated. Outcomes power the Dashboard metrics.
The outcome is derived from the playbook slug and the run's state. Pre-outcome runs use heuristic fallback, historical counts never drop.
Audit
Every tool call, decision, and output is in the run_events log. The audit trail is immutable and workspace-scoped, you can always answer 'what did the agent do and why?'
Run events include the full payload for each action: the GitHub API call, the PR number opened, the Slack message sent. Nothing is summarized away.
Security & threat model
What Conduct protects today, what it does not, and where we're headed. We believe you deserve an honest answer to "is it safe to give this agent my GitHub token?"
What we protect
Credentials encrypted at rest
Every secret is encrypted with AES-256-GCM before writing to the database. The encryption key is an env var, never stored alongside the ciphertext.
Workspace isolation
Every query is scoped to workspace_id. A credential, agent, or run from workspace A is never accessible to workspace B, enforced at the ORM layer on every request.
Human approval gates
Any block can be marked as an approval gate. The run pauses and cannot proceed until an authorized user approves or rejects.
Immutable audit log
run_events are append-only. Every tool call, LLM decision, and output is recorded with a timestamp. There is no delete path for run events.
HMAC-validated webhooks
GitHub webhook payloads are validated with HMAC-SHA256 before the run is created. Unauthenticated payloads are rejected with 401.
Hashed API keys
API keys are SHA-256 hashed before storage. The plaintext is shown once at creation and never stored. A compromised database does not expose working keys.
What we do not protect (yet)
Credential mediation
Credentials are decrypted and passed to the executor at runtime. The executor sees the plaintext token. A compromised executor process could exfiltrate it. Mitigation: the executor runs server-side, not client-side.
Network egress allowlist
Agents can call any external URL during a run. There is no per-environment allowlist today. A misconfigured or malicious playbook could make arbitrary outbound requests.
Runtime isolation
Some blocks execute in the API worker while sandbox-backed execution can run in workspace-scoped environments. Treat sandbox isolation as a configured runtime property, not a blanket guarantee.
Playbook static analysis
Conduct does not analyze a playbook's tool calls before you install it. You should review the YAML before installing third-party or custom playbooks.
Long-term direction
Gating agent actions
When an agent calls a tool that takes a real action (refund, cancel, update, send, delete), Guard evaluates the call against the current policy before the action runs. Warn hands off to a human. Block returns a clean refusal. Every decision lands in the same hash-chained audit as your model calls.
Rules are declarative YAML. Ship a rule without a deploy. Below is a minimal example that caps a support agent's refunds and requires supervisor review above a threshold.
# ~/.conductguard/policies/refund-cap.yaml
name: refund-cap
applies_to:
- "tool:issue_refund"
rules:
- id: block-over-1000
when:
arg.amount_usd: { gt: 1000 }
action: block
reason: "Refund exceeds hard cap. Route to finance."
- id: warn-over-2x-dispute
when:
arg.amount_usd: { gt: "${arg.disputed_amount_usd} * 2" }
action: warn
handoff: supervisor
reason: "Refund is more than twice the disputed amount. Supervisor review required."The same pattern applies to any action tool: cancellation reason lists, pricing commitments, DB writes, outbound sends. See Policy reference for the full rule grammar.
Cedar policy import
Guard accepts policies in Cedar, the AWS-blessed open standard used by AWS Verified Permissions and (via Dogwood) Amazon Bedrock AgentCore. Import Cedar policies from your existing IAM stack, and Guard converts them to its native pack format. Runtime evaluation is unchanged.
CLI import
# Preview conduct import-cedar my-policy.json --pack-slug my-cedar-import --pack-name "My Cedar Import" # Install conduct import-cedar my-policy.json --pack-slug my-cedar-import --pack-name "My Cedar Import" --install
Cedar text export
Every installed pack renders as Cedar text syntax for readability. Click View as Cedar on any pack detail page in the Registry, or fetch it via the API:
GET /guard/registry/packs/{slug}/cedar
GET /guard/registry/packs/{slug}/cedar?version=2.2.0See the full Cedar adapter user guide for the mapping table, error taxonomy, and runnable examples.
