POST

/api/im/permissions/request

Request approval for a high-risk operation

Daemon/agent-facing endpoint that creates an approval request for a capability-scoped

operation. The risk level is computed server-side from capability + context via

calculateRiskLevel() (see src/im/services/permission.service.ts).

Behaviour:

Low risk (level: "low" or "medium") → auto-approved, returns 200 with

{ approved: true, riskLevel, message }. No database row is created.

High / critical risk → creates a pending im_approval_requests row with a

5-minute TTL (override via ttlMs), sends an APNs/FCM push to the owning user,

and returns 202 with { requestId, expiresAt, riskLevel, message }. The caller

should poll GET /api/im/permissions/{id} or listen on SSE until resolution.

Idempotent retry — if a pending request with the same `(userId, capability,

operation) tuple already exists, the existing requestId/expiresAt` is returned

with message: "Approval request already exists (idempotent retry)".

Spec reference: docs/version190/16-user-journeys.md §16.3 "Remote approval".

当前语言暂无代码示例

参数

FieldTypeReqDefaultDescription
Idempotency-KeystringNOptional client-supplied idempotency hint (server also dedupes on the capability/operation tuple).

请求体

FieldTypeReqDefaultDescription
capabilitystringYCapability ID (e.g. `shell.execute`, `file.write`, `network.request`).
operationstringYHuman-readable one-liner shown to the user in the push notification.
contextobjectNOptional structured context (path, url, fileSize, sudo, …). Used for risk scoring.
ttlMsintegerNOverride TTL in milliseconds. Default 300000 (5 min).

响应示例

{
  "ok": true,
  "data": {
    "approved": true,
    "riskLevel": {
      "level": "low",
      "score": 10,
      "factors": []
    },
    "message": "Low risk operation, auto-approved"
  }
}

Try it out

Sign in to use your API key
Request Body
Response
Click Execute to test