Use Cases & Patterns
HARP is intentionally a 1:1 protocol: one request, one pair_id, one human decides. But agent platforms can compose multiple HARP calls to implement sophisticated authorization patterns. This page covers the most common patterns with architecture diagrams and code.
Single Approver (Basic)
Section titled “Single Approver (Basic)”The default HARP flow. One agent, one human. The agent sends an approval request and the human approves or denies on their phone.
When to use: Individual developers using AI agents, personal automation, small teams with a single point of contact.
Example: A developer running Claude Code locally. The agent wants to execute rm -rf /tmp/build. HARP sends the request, the developer reviews on their phone, approves with Face ID.
import { Authorizer, loadPairing } from "@humanauth/sdk";
const pairing = await loadPairing("my-laptop");const auth = new Authorizer(pairing);
const result = await auth.requestApproval({ action: "bash_execute", description: "Remove temporary build directory", parameters: { command: "rm -rf /tmp/build" }, reasoning: "Build cache is stale and consuming 2GB", ttl: 300,});
if (result.decision === "approved") { await execCommand("rm -rf /tmp/build");}Multi-Approver (M-of-N Quorum)
Section titled “Multi-Approver (M-of-N Quorum)”The agent platform sends parallel HARP requests to multiple pair_ids and applies quorum logic locally. The relay knows nothing about the grouping.
When to use: Financial transactions over a threshold, production deployments, compliance-sensitive operations that require multiple sign-offs.
Architecture:
Agent Platform |-- HARP request --> pair_id_1 (CFO) --> APPROVED |-- HARP request --> pair_id_2 (CTO) --> APPROVED +-- HARP request --> pair_id_3 (VP Eng) --> DENIED
Platform logic: 2-of-3 required --> APPROVEDImplementation:
import { Authorizer, loadPairing } from "@humanauth/sdk";
// Load pairings for each approverconst approvers = [ { name: "cfo", pairing: await loadPairing("cfo") }, { name: "cto", pairing: await loadPairing("cto") }, { name: "vp-eng", pairing: await loadPairing("vp-eng") },];
const QUORUM = 2; // 2-of-3 required
const request = { action: "wire_transfer", description: "Transfer $50,000 to vendor account", parameters: { amount: 50000, recipient: "ACME Corp", account: "****7890" }, ttl: 600,};
// Send all requests in parallelconst results = await Promise.allSettled( approvers.map(async ({ name, pairing }) => { const auth = new Authorizer(pairing); const result = await auth.requestApproval(request); return { name, ...result }; }));
// Count approvalsconst approved = results .filter((r) => r.status === "fulfilled" && r.value.decision === "approved") .map((r) => r.value);
if (approved.length >= QUORUM) { console.log(`Quorum reached (${approved.length}/${approvers.length}). Proceeding.`); await executeTransfer();} else { console.log(`Quorum not reached. ${approved.length}/${QUORUM} approvals.`);}Considerations:
- Each approver sees the same request context (or the platform can customize the description per approver)
- Each response is independently signed with Ed25519 — cryptographic non-repudiation per approver
- The platform should handle partial responses (e.g., 2 approved but 1 expired)
- Consider including “1 of 3 approved so far” in the
contextfield for subsequent requests
Escalation Chain
Section titled “Escalation Chain”The agent platform sends a HARP request to the primary approver first. If they do not respond within a shorter TTL, the platform escalates to the next person in the chain.
When to use: On-call workflows, time-sensitive operations, manager escalation for denied requests.
Architecture:
Agent Platform |-- HARP request (TTL=120s) --> pair_id_1 (on-call eng) | +-- EXPIRED (no response in 2 min) |-- HARP request (TTL=180s) --> pair_id_2 (team lead) | +-- APPROVED +-- DoneImplementation:
import { Authorizer, loadPairing } from "@humanauth/sdk";
const escalationChain = [ { name: "on-call-eng", ttl: 120 }, { name: "team-lead", ttl: 180 }, { name: "eng-director", ttl: 300 },];
const baseRequest = { action: "deploy_hotfix", description: "Deploy security hotfix to production", parameters: { service: "auth", version: "1.2.1-hotfix" },};
for (const { name, ttl } of escalationChain) { const pairing = await loadPairing(name); const auth = new Authorizer(pairing);
const result = await auth.requestApproval({ ...baseRequest, reasoning: name === escalationChain[0].name ? "Critical security patch" : `Escalated: ${escalationChain[0].name} did not respond`, ttl, });
if (result.decision === "approved") { console.log(`Approved by ${name}. Deploying hotfix.`); await deployHotfix(); break; } else if (result.decision === "denied") { console.log(`Denied by ${name}: ${result.reason}`); break; // Explicit denial stops the chain } // If expired, continue to next person in chain console.log(`${name} did not respond within ${ttl}s. Escalating...`);}Considerations:
- Explicit denials should stop the chain — do not escalate a denied request
- Include escalation context in the
reasoningfield so the next approver knows why they are being asked - The chain should have a maximum depth (usually 3-4 levels)
Batch Approval
Section titled “Batch Approval”The agent collects multiple pending actions and sends them as a single HARP request for batch review. This reduces notification fatigue for non-urgent operations.
When to use: Nightly batch jobs, agents that queue up non-urgent actions for periodic human review, reducing notification fatigue.
Architecture:
Agent Platform +-- HARP request: action: "batch_approve" parameters: items: - { action: "file_delete", path: "/tmp/old-logs" } - { action: "db_migrate", schema: "users_v3" } - { action: "deploy", service: "api", version: "2.1.0" }Implementation:
import { Authorizer, loadPairing } from "@humanauth/sdk";
const pairing = await loadPairing("ops-lead");const auth = new Authorizer(pairing);
const pendingActions = [ { action: "file_delete", path: "/tmp/old-logs", size: "2.3GB" }, { action: "db_migrate", schema: "users_v3", rows_affected: 15000 }, { action: "deploy", service: "api", version: "2.1.0" },];
const result = await auth.requestApproval({ action: "batch_approve", description: `Batch of ${pendingActions.length} pending actions from overnight run`, parameters: { items: pendingActions }, reasoning: "Nightly maintenance batch collected between 00:00-06:00 UTC", ttl: 600,});
if (result.decision === "approved") { for (const action of pendingActions) { await executeAction(action); }}Considerations:
- The current protocol is all-or-nothing per request. For per-item granularity, send separate requests
- Include clear summaries in the
descriptionfield so the reviewer can quickly assess the batch - The HARP app renders the full
parametersobject, so structured batch data displays clearly
Unattended Agent Fleets
Section titled “Unattended Agent Fleets”Agents running in CI/CD pipelines, cron jobs, or multi-agent orchestration systems. No human watches a terminal — HARP provides the approval channel via push notifications.
When to use: Overnight batch jobs, scheduled agents, CI/CD deployment gates, multi-agent systems that need human sign-off for critical steps.
Architecture:
CI/CD Pipeline +-- Agent step: "deploy to production" +-- HARP request --> pair_id (DevOps lead's phone) +-- Push notification at 3 AM +-- Approve from bed --> deploy proceedsImplementation (GitHub Actions example):
jobs: deploy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: 22
- name: Request deployment approval via HARP run: | npx @humanauth/cli request \ --name "deploy-approver" \ --action "deploy_production" \ --description "Deploy ${{ github.sha }} to production" \ --ttl 600 env: HARP_PAIRINGS_DIR: ${{ secrets.HARP_PAIRINGS_DIR }}
- name: Deploy run: ./scripts/deploy.shConsiderations:
- Push notifications are critical — the human is not watching anything
- Set generous TTL values (max 600s) since response time may be slower at off-hours
- Handle
expiredresponses gracefully: retry later, alert via a backup channel, or fail safe - Store the pairing file as a CI secret (it contains the encryption keys)
Cross-Platform Approval
Section titled “Cross-Platform Approval”A single HARP app on the user’s phone, paired with multiple agent platforms. One app manages all agent authorizations.
When to use: Any user with multiple AI agent integrations — personal laptop, work agents, home automation, trading bots.
Architecture:
HARP App (user's phone) |-- Paired with: Claude Code (personal laptop) |-- Paired with: Company AI Agent (work) |-- Paired with: Home Automation Agent +-- Paired with: Trading BotEach pairing has independent keys. Compromising one platform does not affect others. The app’s Home screen groups pending requests by platform for clarity, and any pairing can be revoked independently.
Setup:
# Pair with personal laptophumanauth pair --name "personal-laptop" --relay https://relay.humanauth.ai
# Pair with work agenthumanauth pair --name "work-agent" --relay https://relay.humanauth.ai
# Pair with home automationhumanauth pair --name "home-auto" --relay https://relay.humanauth.ai
# List all pairingshumanauth listNAME PAIR_ID RELAY PAIREDpersonal-laptop pair_a1b2c3d4e5f6 https://relay.humanauth.ai 2026-04-10work-agent pair_x7y8z9w0v1u2 https://relay.humanauth.ai 2026-04-11home-auto pair_m3n4o5p6q7r8 https://relay.humanauth.ai 2026-04-12Conditional Approval with Feedback
Section titled “Conditional Approval with Feedback”The user denies a request with a reason, and the agent adapts its approach based on the feedback. Denial is not a dead end — it is a course correction.
When to use: Interactive agent workflows where the human wants to guide the agent rather than simply block it.
Architecture:
Agent: "Run: rm -rf /home/user/projects" +-- HARP request --> user +-- DENIED, reason: "Too broad. Only delete /home/user/projects/tmp" +-- Agent adapts: "Run: rm -rf /home/user/projects/tmp" +-- HARP request --> user +-- APPROVEDImplementation:
import { Authorizer, loadPairing } from "@humanauth/sdk";
const pairing = await loadPairing("my-laptop");const auth = new Authorizer(pairing);
let command = "rm -rf /home/user/projects";const MAX_RETRIES = 3;
for (let attempt = 0; attempt < MAX_RETRIES; attempt++) { const result = await auth.requestApproval({ action: "bash_execute", description: `Execute: ${command}`, parameters: { command }, reasoning: attempt === 0 ? "Cleaning up disk space" : `Adjusted based on feedback: ${previousReason}`, ttl: 300, });
if (result.decision === "approved") { await execCommand(command); break; }
if (!result.reason) { console.log("Denied without feedback. Stopping."); break; }
// Pass the denial reason to the LLM to adapt const previousReason = result.reason; command = await llm.adjustCommand(command, result.reason); console.log(`Adjusted command to: ${command}`);}Considerations:
- The
reasonfield in the denial response is passed back to the agent — no protocol changes needed - Set a maximum retry count to prevent infinite loops
- The agent (or its orchestrating LLM) interprets the feedback and adjusts the action
- Each retry is a fresh HARP request with a new
request_id
Audit & Compliance
Section titled “Audit & Compliance”Both sides of the protocol retain full plaintext independently. The relay retains zero plaintext. This architecture is purpose-built for compliance environments.
Platform side: The SDK automatically logs to ~/.harp/audit/YYYY-MM-DD.jsonl — every request sent, every response received, full plaintext.
{"timestamp":"2026-04-12T10:30:00Z","request_id":"req_abc123","pair_id":"pair_xyz","action":"deploy_production","description":"Deploy API v2.1","decision":"approved","signature":"base64..."}{"timestamp":"2026-04-12T10:45:00Z","request_id":"req_def456","pair_id":"pair_xyz","action":"db_migrate","description":"Migrate users table","decision":"denied","reason":"Not during peak hours"}App side: On-device history stored in SQLite. Full decrypted context for every request. Exportable for personal records.
When to use: SOC2, HIPAA, SOX, or any environment requiring proof of human authorization for agent actions.
Considerations:
- The relay retains zero plaintext — audit logs exist only at the endpoints
- For enterprise deployments, platform-side audit logs can be shipped to SIEM systems (Splunk, Datadog, etc.)
- Ed25519 signatures provide cryptographic non-repudiation: proof that a specific device (and biometric-authenticated human) approved a specific action at a specific time
- Each approval is independently verifiable — signatures can be checked without contacting the relay