Skip to content
This repository was archived by the owner on Apr 16, 2026. It is now read-only.
This repository was archived by the owner on Apr 16, 2026. It is now read-only.

Implement approval notification transport with signed callbacks #3

@haasonsaas

Description

@haasonsaas

Summary

The approval gating flow works (create approval, approve/deny via API) but there is no way to notify an approver that a decision is needed. The notifier interface exists but has no implementation.

Current state

  • internal/app/service.go:271-275 — notifier is nil-checked and called, but no real implementation is wired
  • Approvals have a hardcoded 5-minute TTL (service.go:18-19) — if nobody is notified, they silently expire
  • README states: "no full production approval callback transport yet"

Required work

  • Implement at least one approval notification transport (webhook is the obvious first choice)
  • Sign approval callback payloads with HMAC or asymmetric signature so the receiver can verify authenticity
  • Add replay protection: include a nonce and timestamp in the callback, reject stale or duplicate callbacks
  • Add retry logic with exponential backoff for failed deliveries
  • Track notification delivery status (pending, delivered, failed) on the approval record
  • Make approval TTL configurable (currently hardcoded at 5 minutes)
  • Wire the notifier implementation into bootstrap

Design considerations

  • Webhook is the simplest first transport, but consider NATS/JetStream for internal use cases
  • The callback should include: approval_id, grant_id, tenant_id, capability, resource, tool, requested_by, and an approve/deny URL pair
  • Callback URLs should be pre-registered per tenant, not dynamically generated

Files

  • internal/app/service.go — notifier call site
  • New package: internal/approval/webhook/ or internal/approval/transport/
  • internal/bootstrap/service.go — wire the implementation

Priority

High — approvals without notifications are effectively unusable in production.

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions