{"openapi":"3.1.0","info":{"title":"Agent Secret Lease API","version":"1.0.0","summary":"Let AI agents use API credentials without ever seeing them.","description":"Agents request a short-lived **lease** on an owner-defined policy, then send HTTPS requests through `POST /api/v1/leases/{id}/execute`. The proxy checks the lease and policy (host, method, path), blocks private/internal destinations (SSRF), injects the credential server-side and returns the upstream response with any echo of the credential redacted. The credential value is never returned by any endpoint.\n\nPricing: the owner’s plan includes a monthly free lease allowance; beyond it each lease costs 0.01 USDC via x402 v2 (exact scheme, USDC on Base). Rejected lease requests are never charged.\n\nErrors always use `{\"error\":{\"code\",\"message\",\"retryable\"}}`. Agent auth: `Authorization: Bearer asl_agent_…` (issued once by the owner). Owner endpoints use the dashboard session cookie.\n\nOperated by ActivLife Hub LLC."},"servers":[{"url":"https://agentsecretlease.online"}],"externalDocs":{"url":"https://agentsecretlease.online/docs"},"components":{"securitySchemes":{"agentToken":{"type":"http","scheme":"bearer","description":"Agent token asl_agent_… (shown once at creation)."},"ownerSession":{"type":"apiKey","in":"cookie","name":"asl_session","description":"Owner dashboard session (magic-link sign-in). Writes require a same-origin Origin header."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","retryable"],"properties":{"code":{"type":"string","enum":["UNAUTHORIZED","FORBIDDEN","NOT_FOUND","VALIDATION_ERROR","AGENT_REVOKED","AGENT_NOT_FOUND","SECRET_NOT_FOUND","POLICY_NOT_FOUND","POLICY_DENIED","LEASE_NOT_FOUND","LEASE_PENDING","LEASE_EXPIRED","LEASE_REVOKED","LEASE_EXHAUSTED","HOST_NOT_ALLOWED","METHOD_NOT_ALLOWED","PATH_NOT_ALLOWED","DESTINATION_BLOCKED","PLAN_LIMIT_REACHED","PAYMENT_REQUIRED","PAYMENT_FAILED","PAYMENT_UNAVAILABLE","IDEMPOTENCY_KEY_REQUIRED","IDEMPOTENCY_CONFLICT","DUPLICATE_REQUEST","RATE_LIMITED","PAYLOAD_TOO_LARGE","UNSUPPORTED_MEDIA_TYPE","UPSTREAM_ERROR","UPSTREAM_TIMEOUT","UPSTREAM_REDIRECT_BLOCKED","UPSTREAM_RESPONSE_TOO_LARGE","EMAIL_UNAVAILABLE","SERVICE_UNAVAILABLE"]},"message":{"type":"string"},"retryable":{"type":"boolean"},"details":{"type":"object"}}}}},"Lease":{"type":"object","properties":{"id":{"type":"string","example":"lease_…"},"status":{"type":"string","enum":["pending","active","expired","revoked","exhausted"]},"policy_id":{"type":"string"},"agent_id":{"type":"string"},"secret_id":{"type":"string"},"billing":{"type":"string","enum":["free","paid"]},"price":{"type":"string"},"currency":{"type":"string","const":"USDC"},"created_at":{"type":"string","format":"date-time"},"activated_at":{"type":["string","null"],"format":"date-time"},"expires_at":{"type":["string","null"],"format":"date-time"},"max_requests":{"type":"integer"},"used_requests":{"type":"integer"},"remaining_requests":{"type":"integer"},"execute_url":{"type":"string","format":"uri"}}},"LeaseRequest":{"type":"object","required":["policy_id"],"additionalProperties":false,"properties":{"policy_id":{"type":"string","pattern":"^pol_[0-9a-f]{32}$"},"duration_seconds":{"type":"integer","minimum":1,"maximum":3600,"description":"Default and maximum: the policy’s max_lease_seconds."},"max_requests":{"type":"integer","minimum":1,"maximum":1000,"description":"Default and maximum: the policy’s max_requests_per_lease."}}},"ExecuteRequest":{"type":"object","required":["method","url"],"additionalProperties":false,"properties":{"method":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE"]},"url":{"type":"string","format":"uri","description":"https:// only, port 443, DNS hostname on the policy allowlist."},"headers":{"type":"object","additionalProperties":{"type":"string"},"description":"Max 30. Authorization, Cookie, Host, Proxy-*, X-Forwarded-*, Accept-Encoding and the credential header are refused."},"body":{"description":"String or JSON (JSON sets Content-Type: application/json). Max 64 KB."},"body_base64":{"type":"string","description":"Binary body alternative to body."}}},"ExecuteResponse":{"type":"object","properties":{"lease":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string"},"remaining_requests":{"type":"integer"},"expires_at":{"type":"string"}}},"upstream":{"type":"object","properties":{"status":{"type":"integer"},"headers":{"type":"object","additionalProperties":{"type":"string"}},"body":{"type":"string"},"body_encoding":{"type":"string","enum":["utf8","base64"]},"redactions":{"type":"integer","description":"Occurrences of the credential scrubbed from the response."},"duration_ms":{"type":"integer"}}}}},"Policy":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"agent_id":{"type":"string"},"secret_id":{"type":"string"},"allowed_hosts":{"type":"array","items":{"type":"string"}},"allowed_methods":{"type":"array","items":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE"]}},"allowed_path_prefixes":{"type":"array","items":{"type":"string"}},"max_lease_seconds":{"type":"integer","minimum":30,"maximum":3600},"max_requests_per_lease":{"type":"integer","minimum":1,"maximum":1000},"total_request_limit":{"type":["integer","null"]},"enabled":{"type":"boolean"},"expires_at":{"type":["string","null"],"format":"date-time"}}},"PolicyInput":{"type":"object","required":["agent_id","secret_id","allowed_hosts","allowed_methods","allowed_path_prefixes","max_lease_seconds","max_requests_per_lease"],"properties":{"agent_id":{"type":"string"},"secret_id":{"type":"string"},"name":{"type":"string"},"allowed_hosts":{"type":"array","items":{"type":"string"},"maxItems":10},"allowed_methods":{"type":"array","items":{"type":"string","enum":["GET","HEAD","POST","PUT","PATCH","DELETE"]}},"allowed_path_prefixes":{"type":"array","items":{"type":"string"},"maxItems":20},"max_lease_seconds":{"type":"integer","minimum":30,"maximum":3600},"max_requests_per_lease":{"type":"integer","minimum":1,"maximum":1000},"total_request_limit":{"type":["integer","null"]},"enabled":{"type":"boolean"},"expires_at":{"type":["string","null"],"format":"date-time"}}},"Secret":{"type":"object","description":"Metadata only. The credential value is never returned.","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"secret_type":{"type":"string","enum":["bearer_token","api_key_header","api_key_query","basic_auth","custom_header"]},"injection":{"type":"object"},"status":{"type":"string"},"value":{"type":["string","null"],"const":"stored securely (never shown again)"}}},"AuditEvent":{"type":"object","properties":{"id":{"type":"string"},"at":{"type":"string"},"event":{"type":"string"},"actor":{"type":"string"},"agent_id":{"type":["string","null"]},"secret_id":{"type":["string","null"]},"policy_id":{"type":["string","null"]},"lease_id":{"type":["string","null"]},"host":{"type":["string","null"]},"method":{"type":["string","null"]},"path":{"type":["string","null"]},"status_code":{"type":["integer","null"]},"duration_ms":{"type":["integer","null"]},"result":{"type":["string","null"]}}}}},"paths":{"/api/v1/capabilities":{"get":{"operationId":"listCapabilities","summary":"Policies this agent may lease, usage, and the price of the next lease","security":[{"agentToken":[]}],"responses":{"200":{"description":"Capabilities","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/leases":{"post":{"operationId":"requestLease","summary":"Request a lease (free within allowance; otherwise x402 402 → pay → retry)","description":"Without PAYMENT-SIGNATURE when payment is due: 402 with the x402 v2 requirement in the body (`x402`) and the PAYMENT-REQUIRED header. Resend the identical body with PAYMENT-SIGNATURE and the same Idempotency-Key. Policy checks run before any payment; rejected requests are never charged. One payment authorization pays for exactly one lease (replays are refused).","security":[{"agentToken":[]}],"parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{16,128}$"},"required":true},{"name":"PAYMENT-SIGNATURE","in":"header","required":false,"schema":{"type":"string"},"description":"base64 x402 v2 payment payload"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeaseRequest"}}}},"responses":{"200":{"description":"Idempotent replay of an earlier request","content":{"application/json":{"schema":{"type":"object","properties":{"lease":{"$ref":"#/components/schemas/Lease"},"replayed":{"type":"boolean"}}}}}},"201":{"description":"Lease created (header PAYMENT-RESPONSE when paid)","content":{"application/json":{"schema":{"type":"object","properties":{"lease":{"$ref":"#/components/schemas/Lease"},"replayed":{"type":"boolean"}}}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"402":{"description":"Payment required or payment failed","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/Error"},"x402":{"type":"object"}}}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"get":{"operationId":"listLeases","summary":"List leases (agent: own; owner: all)","security":[{"agentToken":[]},{"ownerSession":[]}],"parameters":[{"name":"status","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Leases","content":{"application/json":{"schema":{"type":"object","properties":{"leases":{"type":"array","items":{"$ref":"#/components/schemas/Lease"}}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/leases/{id}":{"get":{"operationId":"getLease","summary":"Lease status (expiry is computed at read time)","security":[{"agentToken":[]},{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"lease_…"}],"responses":{"200":{"description":"Lease","content":{"application/json":{"schema":{"type":"object","properties":{"lease":{"$ref":"#/components/schemas/Lease"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/leases/{id}/execute":{"post":{"operationId":"executeWithLease","summary":"Send one HTTPS request through the lease; the credential is injected server-side","description":"Consumes one request from the lease. Redirects are never followed (UPSTREAM_REDIRECT_BLOCKED). Destinations resolving to loopback, private, link-local, metadata or reserved addresses are refused (DESTINATION_BLOCKED). The upstream status is in `upstream.status`; the HTTP status is 200 whenever the upstream answered. Optional Idempotency-Key prevents a retried call from being sent twice.","security":[{"agentToken":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"lease_…"},{"name":"Idempotency-Key","in":"header","schema":{"type":"string","pattern":"^[A-Za-z0-9_-]{16,128}$"},"required":false}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteRequest"}}}},"responses":{"200":{"description":"Upstream response","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ExecuteResponse"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"410":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"413":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"502":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"504":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/leases/{id}/revoke":{"post":{"operationId":"revokeLease","summary":"Revoke or release a lease (agent: own; owner: any)","security":[{"agentToken":[]},{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"lease_…"}],"responses":{"200":{"description":"Lease","content":{"application/json":{"schema":{"type":"object","properties":{"lease":{"$ref":"#/components/schemas/Lease"},"changed":{"type":"boolean"}}}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/policies":{"get":{"operationId":"listPolicies","summary":"List policies (agent: own; owner: all)","security":[{"agentToken":[]},{"ownerSession":[]}],"responses":{"200":{"description":"Policies","content":{"application/json":{"schema":{"type":"object","properties":{"policies":{"type":"array","items":{"$ref":"#/components/schemas/Policy"}}}}}}}}},"post":{"operationId":"createPolicy","summary":"Create a policy (owner)","security":[{"ownerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyInput"}}}},"responses":{"201":{"description":"Policy","content":{"application/json":{"schema":{"type":"object","properties":{"policy":{"$ref":"#/components/schemas/Policy"}}}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/policies/{id}":{"get":{"operationId":"getPolicy","summary":"Get a policy","security":[{"agentToken":[]},{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"pol_…"}],"responses":{"200":{"description":"Policy","content":{"application/json":{"schema":{"type":"object","properties":{"policy":{"$ref":"#/components/schemas/Policy"}}}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updatePolicy","summary":"Update a policy (owner); active leases follow the new rules immediately","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"pol_…"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PolicyInput"}}}},"responses":{"200":{"description":"Policy","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"revokePolicy","summary":"Revoke a policy and its active leases (owner)","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"pol_…"}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/secrets":{"get":{"operationId":"listSecrets","summary":"List secrets (metadata only, owner)","security":[{"ownerSession":[]}],"responses":{"200":{"description":"Secrets","content":{"application/json":{"schema":{"type":"object","properties":{"secrets":{"type":"array","items":{"$ref":"#/components/schemas/Secret"}}}}}}}}},"post":{"operationId":"createSecret","summary":"Store a credential (encrypted with AES-256-GCM; never shown again)","security":[{"ownerSession":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","secret_type","value"],"properties":{"name":{"type":"string"},"description":{"type":"string"},"secret_type":{"type":"string","enum":["bearer_token","api_key_header","api_key_query","basic_auth","custom_header"]},"value":{"type":"string","writeOnly":true},"injection":{"type":"object","properties":{"header_name":{"type":"string"},"query_param":{"type":"string"},"value_prefix":{"type":"string"}}}}}}}},"responses":{"201":{"description":"Secret metadata","content":{"application/json":{"schema":{"type":"object","properties":{"secret":{"$ref":"#/components/schemas/Secret"}}}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/secrets/{id}":{"get":{"operationId":"getSecret","summary":"Secret metadata","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"sec_…"}],"responses":{"200":{"description":"Secret","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"operationId":"updateSecret","summary":"Rename or rotate a secret","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"sec_…"}],"responses":{"200":{"description":"Secret","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"operationId":"deleteSecret","summary":"Erase the credential; its policies and active leases stop immediately","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"sec_…"}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/agents":{"get":{"operationId":"listAgents","summary":"List agents (owner)","security":[{"ownerSession":[]}],"responses":{"200":{"description":"Agents","content":{"application/json":{"schema":{"type":"object"}}}}}},"post":{"operationId":"createAgent","summary":"Create an agent identity; the token is returned once","security":[{"ownerSession":[]}],"responses":{"201":{"description":"Agent and token","content":{"application/json":{"schema":{"type":"object"}}}},"400":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/agents/{id}":{"delete":{"operationId":"revokeAgent","summary":"Revoke an agent and its active leases","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"agt_…"}],"responses":{"200":{"description":"Revoked","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/agents/{id}/rotate":{"post":{"operationId":"rotateAgentToken","summary":"Rotate an agent token (old token stops working)","security":[{"ownerSession":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"agt_…"}],"responses":{"200":{"description":"New token (shown once)","content":{"application/json":{"schema":{"type":"object"}}}},"404":{"description":"Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/v1/audit":{"get":{"operationId":"listAudit","summary":"Audit events (agent: own; owner: all). Never contains credentials, Authorization headers, bodies or query strings.","security":[{"agentToken":[]},{"ownerSession":[]}],"parameters":[{"name":"before","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"string"}},{"name":"event","in":"query","schema":{"type":"string"}},{"name":"lease_id","in":"query","schema":{"type":"string"}},{"name":"agent_id","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Events","content":{"application/json":{"schema":{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/AuditEvent"}},"next_before":{"type":["string","null"]}}}}}}}}},"/api/v1/pricing":{"get":{"operationId":"getPricing","summary":"Plans and lease price","security":[],"responses":{"200":{"description":"Pricing","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/v1/health":{"get":{"operationId":"getHealth","summary":"Configuration readiness (no database access)","security":[],"responses":{"200":{"description":"Ready","content":{"application/json":{"schema":{"type":"object"}}}},"503":{"description":"Not configured","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/api/mcp":{"post":{"operationId":"mcp","summary":"MCP (Streamable HTTP, stateless JSON). Tools: list_capabilities, request_lease, get_lease, execute_with_lease, revoke_lease","security":[{"agentToken":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object"}}}},"responses":{"200":{"description":"JSON-RPC response","content":{"application/json":{"schema":{"type":"object"}}}},"202":{"description":"Notification accepted"}}}}}}