edl: 0.1
name: claims-refund-reviewer
version: 1.2.0
agent:
  id: "agent:RefundReviewer"
  kind: agent
  image: "ghcr.io/acme/refund-reviewer@sha256:REPLACE_WITH_DIGEST"
  command:
    - refund-reviewer
    - run
  workdir: /workspace
  supply_chain:
    image_digest_required: true
    signed_image_required: true
    sbom_required: true
authority:
  principals:
    - id: "human:ClaimsLead"
      kind: human
      identity: passkey_or_oidc
    - id: "agent:RefundReviewer"
      kind: agent
      identity: cryptographic
      credential: short_lived
      attestation: required
  mandates:
    - id: "mandate:claims-refund-reviewer"
      issued_by: "human:ClaimsLead"
      issued_to: "agent:RefundReviewer"
      purpose: Review refund requests and issue approved small refunds through mediated gates.
      valid_for: 30m
      revocable: true
  delegations:
    - id: "delegation:claims-refund-reviewer"
      from: "human:ClaimsLead"
      to: "agent:RefundReviewer"
      mandate: "mandate:claims-refund-reviewer"
      may_delegate: false
      expires_after: 30m
  capabilities:
    - id: "cap:db-read-customerdb-claims"
      principal: "agent:RefundReviewer"
      effects:
        - db.read.CustomerDB.claims
      resources:
        - CustomerDB.claims
      ttl: 10m
    - id: "cap:http-call-refundapi-issue-refund"
      principal: "agent:RefundReviewer"
      effects:
        - http.call.RefundAPI.issue_refund
      resources:
        - RefundAPI.issue_refund
      ttl: 5m
      single_use: true
      requires:
        approval: "human:ClaimsLead"
        liveness: passkey
      max_amount_usd: 100
enclosure:
  id: "enc:claims-refund-reviewer"
  mode: enforce
  backend_preference:
    - docker
    - seatbelt
  fail_closed: true
  filesystem:
    root: read_only
    workdir:
      path: /workspace
      access: read_write
    mounts:
      - host: ./workspace
        guest: /workspace
        access: read_write
    deny:
      - ~/.ssh
      - ~/.git-credentials
      - ~/.config/gh
      - /var/run/docker.sock
  network:
    default: deny
    allow:
      - id: doorkeeper
        url: "https://doorkeeper.internal"
        ports:
          - 443
  process:
    user: non_root
    no_new_privileges: true
    drop_linux_capabilities: all
    seccomp: default_or_stricter
    pids_max: 256
    timeout: 30m
    cpu: 2
    memory: 4Gi
    disallow:
      - docker
      - gh auth
      - ssh-add
  secrets:
    ambient: deny
    host_keychain: deny
    ssh_agent: deny
    mount_tokens: deny
    allowed_runtime_tokens:
      - audience: doorkeeper
        ttl: 5m
gates:
  - id: "gate:capsule"
    kind: mcp_doorkeeper
    endpoint: "https://doorkeeper.internal/mcp"
    target: claims-refund-reviewer
    credential_custody: server_side_only
    actions:
      - effect: db.read.CustomerDB.claims
        decision: allow
        requires_receipt: true
        parameters:
          require_schema: schemas/db-read-customerdb-claims.json
      - effect: http.call.RefundAPI.issue_refund
        decision: escalate
        requires_receipt: true
        requires_capability: "cap:http-call-refundapi-issue-refund"
        postcondition:
          event: http.call.RefundAPI.issue_refund.completed
          verify: "receipt.effect == \"http.call.RefundAPI.issue_refund\""
policies:
  - id: "policy:capsule"
    default: deny
    rules:
      - when: "effect == \"db.read.CustomerDB.claims\""
        decision: allow
      - when: "effect == \"http.call.RefundAPI.issue_refund\" and (amount_usd > 50)"
        decision: escalate
        require:
          - approval
          - liveness
          - single_use_capability
memory:
  default: isolated
  stores:
    - id: "mem:refund-session"
      isolation: per_session
      ttl: 24h
      source_attribution: required
      hash_validation: on_read
telemetry:
  required: true
  trace: opentelemetry
  tamper_evident: true
  export:
    - otel
    - siem
    - ledger
  must_emit:
    - invocation.start
    - invocation.end
    - enclosure.attested
    - policy.evaluated
    - capability.issued
    - effect.intent
    - effect.denied
    - effect.escalated
    - effect.executed
    - receipt.emitted
  include:
    - trace_id
    - span_id
    - agent_id
    - principal_id
    - mandate_id
    - delegation_id
    - capability_jti
    - contract_hash
    - enclosure_id
    - effect_intent_id
    - policy_id
    - gate_id
receipts:
  action_bound: true
  single_use_for_high_risk: true
  postcondition_required_for:
    - http.call.RefundAPI.issue_refund
reconciliation:
  - id: "recon:http-call-refundapi-issue-refund"
    source: gate.receipt
    events:
      - http.call.RefundAPI.issue_refund.completed
    match_receipt:
      event: effect_executed
      fields:
        - effect
        - principal_id
        - capability_jti
    on_missing_receipt: violation
    on_non_gate_actor: violation
assertions:
  impossible:
    - agent_has_target_credential
    - agent_can_reach_protected_target_directly
    - protected_effect_without_receipt
  negative_tests:
    - name: protected_effect_requires_gate
      attempt: direct-call http.call.RefundAPI.issue_refund
      expect: mediated_gate_required
compile:
  targets:
    - capsulang
    - docker
    - seatbelt
    - doorkeeper
    - telemetry
    - negative_tests
