Edictum
Guides

Industry Scenarios

Four production-ready governance scenarios from edictum-demo covering pharma, fintech, customer support, and DevOps.

AI Assistance

Right page if: you need production-ready contract examples for pharma (HIPAA), fintech (SOX/MiFID II), customer support (GDPR), or DevOps (SOC 2) from edictum-demo. Wrong page if: you need to write contracts from scratch -- see https://docs.edictum.ai/docs/guides/writing-contracts. For Python decorator contracts specifically, see https://docs.edictum.ai/docs/guides/python-contracts. Gotcha: the DevOps scenario uses Python decorator contracts while the other three use YAML. Claims-based authorization (principal.claims.trade_approval) gates actions without changing the user's role -- useful for temporary approvals.

Four production-ready governance scenarios ship in the edictum-demo repository. Each includes complete contracts, mock tools, principal configurations, and runnable agent code. Use them as starting points for your own contracts.


Pharmacovigilance

Path: scenarios/pharma/ | Framework: LangChain + LangGraph | Compliance: HIPAA, 21 CFR 11, ICH-E6

A clinical-trial agent governed by 7 contracts across access control, change control, and data protection.

Contracts

ContractTypeWhat it enforces
restrict-patient-datapreRole-based access: only pharmacovigilance, clinical_data_manager, and medical_monitor roles can query clinical datasets
no-unblindingpreBlocks unblinding queries during active trials
case-report-requires-ticketpreCAPA/deviation ticket required for case report updates
case-report-authorized-rolespreOnly pharmacovigilance and clinical_data_manager roles can update case reports
pii-in-any-outputpostDetects SSN, patient IDs, email, phone, DOB via regex
regulatory-export-piipostEnhanced PII detection for regulatory document exports
session-limitssessionMax 20 calls, 3 case reports, 2 exports per session

Key patterns demonstrated

  • Multi-role RBAC: Four roles (researcher, pharmacovigilance, clinical_data_manager, medical_monitor) with different access levels
  • Change control: Ticket reference required for state-mutating operations
  • Postcondition PII scanning: Regex-based detection for SSN (\b\d{3}-\d{2}-\d{4}\b), patient IDs, email, phone
  • Per-tool session limits: Different caps for different tool sensitivity levels

Running it

cd scenarios/pharma
python pharma_agent.py --role pharmacovigilance
python pharma_agent.py --role researcher  # denied access to clinical data

Fintech / Trading Compliance

Path: scenarios/fintech/ | Framework: LangChain + LangGraph | Compliance: SOX, MiFID II, PCI-DSS

A trading compliance agent governed by 7 contracts covering trade limits, account access, and data protection.

Contracts

ContractTypeWhat it enforces
trade-size-limitpreTrades >1000 shares denied unless principal.claims.trade_approval is true
account-access-controlpreFull account data restricted to senior_trader, compliance_officer, risk_manager
no-restricted-accountspreBlocks access to frozen/under-investigation accounts (FROZEN, RESTRICTED prefix)
compliance-report-requires-ticketpreAudit ticket required for compliance report generation
pii-in-outputpostWarns on SSN, account numbers, email, phone in output
pii-in-compliance-reportpostEnhanced PII detection for compliance report outputs
session-limitssessionMax 15 calls, 5 trades, 2 compliance reports

Key patterns demonstrated

  • Claims-based authorization: principal.claims.trade_approval: true gates high-value trades without changing the user's role. See Principals for how claims work.
when:
  all:
    - args.quantity: { gt: 1000 }
    - principal.claims.trade_approval: { not_equals: true }
  • Pattern-based blocking: Account IDs containing FROZEN or RESTRICTED markers are denied via contains_any
  • Quantitative thresholds: Numeric comparison operators (gt) for trade size limits
  • Tiered roles: analyst < senior_trader < compliance_officer < risk_manager

Running it

cd scenarios/fintech
python fintech_agent.py --role analyst          # denied large trades
python fintech_agent.py --role senior_trader    # allowed with trade_approval claim

Customer Support

Path: scenarios/customer-support/ | Framework: LangChain + LangGraph | Compliance: GDPR, PCI-DSS

A support-ticket agent governed by 7 contracts covering access control, refund limits, escalation rules, and PII redaction.

Contracts

ContractTypeWhat it enforces
billing-access-controlpreBilling data restricted to senior_agent, supervisor, billing_specialist
refund-limitpreRefunds >$500 require supervisor or billing_specialist role
escalation-requires-reasonpreEscalations must include a documented reason
ticket-update-authorized-rolespreOnly senior agents and supervisors can close tickets
pii-in-outputpostWarns on email, phone, address, partial card numbers
pii-in-customer-lookuppostEnhanced PII detection for customer lookup results
session-limitssessionMax 20 calls, 5 lookups, 3 refunds, 2 escalations

Key patterns demonstrated

  • Financial thresholds: Refunds above $500 gated by role
  • Operational workflow enforcement: Escalations require a reason field (not just RBAC)
when:
  any:
    - args.reason: { exists: false }
    - args.reason: { equals: "" }
  • Data minimization: PII detection includes partial credit card numbers (****1234 pattern)
  • Ticket lifecycle control: Only authorized roles can transition tickets to closed state

Running it

cd scenarios/customer-support
python support_agent.py --role support_agent     # limited access
python support_agent.py --role supervisor       # full access

DevOps / File Organizer

Path: scenarios/devops/ | Framework: OpenAI SDK (via OpenRouter) | Compliance: SOC 2

A file-organizer agent governed by Python-based contracts (not YAML). This scenario demonstrates the decorator contract API.

Contracts (Python)

ContractTypeWhat it enforces
deny_sensitive_reads()pre (built-in)Blocks reads of .env, .ssh, kubernetes secrets, and other sensitive paths
no_destructive_commandspre (custom)Blocks rm, rmdir, shred commands
require_target_dirpre (factory)Confines mv targets to /tmp/
limit_total_operationssessionCaps at 25 bash operations per session
check_bash_errorspostWarns when bash output contains error indicators (No such file, Permission denied)

Key patterns demonstrated

  • Python decorator API: Contracts defined with @precondition, @postcondition, and @session_contract decorators instead of YAML
  • Built-in contract: deny_sensitive_reads() provides instant secret-file protection with no configuration
  • Factory pattern: Parameterized preconditions for reuse across different base paths
from edictum import precondition, Verdict

@precondition("Bash")
def no_destructive_commands(envelope):
    cmd = envelope.bash_command
    if any(d in cmd.split() for d in ["rm", "rmdir", "shred"]):
        return Verdict.fail(f"Destructive command denied: {cmd}")
    return Verdict.pass_()
  • Self-correction: When the agent is denied, it reads the denial message and adjusts its approach (e.g., uses cp instead of mv to a restricted target)
  • Compared with unguarded baseline: demo_without.py shows the same agent reading .env files and running rm -rf without governance

Running it

cd scenarios/devops
python demo_with.py      # governed: destructive commands denied
python demo_without.py   # unguarded: reads .env, runs rm -rf

When to use YAML vs Python contracts

The pharma, fintech, and customer-support scenarios use YAML contracts. The DevOps scenario uses Python decorators. Both approaches enforce identically -- the choice depends on your workflow:

FactorYAMLPython
Managed bySecurity/compliance teamDevelopment team
Hot-reloadableYes (via console SSE)No (requires restart)
Custom logicLimited to operators and expressionsFull Python (envelope introspection, external API calls)
Testable with CLIedictum validate, edictum testStandard pytest
Version controlStandalone YAML filesIn-code with application

Most teams start with YAML and add Python contracts only for logic that cannot be expressed with built-in operators.


Running all scenarios

All scenarios support a --role flag and an observe mode flag. The observe mode flag varies between scenarios:

python <scenario>.py --role <role>       # set the principal role

# DevOps and Pharma scenarios:
python <scenario>.py --observe           # log but don't deny

# Fintech and Customer-Support scenarios:
python <scenario>.py --mode observe      # log but don't deny

See the edictum-demo README for setup instructions and environment variables.

Last updated on

On this page