{
  "schema": "aaes/capability-pack/1",
  "provider": "ringcentral",
  "version": "1.0.0",
  "description": "RingCentral REST API with OAuth2 JWT-grant: read extensions, messages and call logs, send SMS, and delete messages from the message store.",
  "notes": "The endpoint host 'ringcentral-platform.invalid' is a reserved non-production placeholder (an RFC 2606 reserved TLD): substitute the RingCentral platform host (platform.ringcentral.com for production) before enabling, in every endpoint, in the resource locator and in every egress allowlist entry. The allowlist matches exactly, so endpoints and allowlist must be substituted together, and substitution is a required deployment step — the reserved host being allowlisted does not make an unsubstituted pack safe to enable.\n\nThis pack registers only operations the retrieved RingCentral documentation establishes: listing account extensions, reading an extension's message store, reading an extension's call log, sending SMS, and deleting a message from the message store.\n\nACCOUNT_ID, EXTENSION_ID and MESSAGE_ID in the endpoint paths are placeholders the deployment binds before enabling; the API also accepts the '~' shorthand for the account and extension of the authenticated user. RingCentral enforces the app's scopes and the authenticated extension's permissions on every call: SMS can be sent only from numbers owned by the authenticated extension (or company numbers whose SMS assignment points at that extension), and even a super admin cannot send SMS on behalf of other user extensions; the registration records the endpoint, not RingCentral's authorization decision.\n\nThe interactive API reference at developers.ringcentral.com was not machine-readable from the review environment (it refused non-browser clients), so the review was made against RingCentral's official documentation repository on GitHub, which the reference pages are built from — a documented source substitution, named in the review block.\n\nDocumented exclusions — this pack does not register: fax sending (POST.../fax — the same send-class risk as SMS, deliberately left out); company pager messaging; ring-out and the active call-control APIs (initiating, transferring, recording or dropping live calls is a real-time voice surface requiring its own review); call recording content and metadata access; presence and call-forwarding/answering-rule changes; phone number provisioning and emergency addresses; webhook subscriptions and event notifications; and account or extension administration (creating, modifying or deleting extensions).",
  "credential": {
    "secret_ref_id": "secret-ref-ringcentral-access-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "A RingCentral OAuth access token, externally produced and renewed, held in the client's own secret manager. This reference defines ONE stored value and nothing else: the complete Authorization header value (scheme included), 'Bearer ' followed by the access token. The JWT assertion generated in the RingCentral Developer Console for the service extension, and the app's client ID and client secret, are NOT stored under this reference — they belong under separate credential references that only the deployment's custody job may resolve.\n\nRingCentral documents an RFC 7523 OAuth flow: the custody job POSTs to /restapi/oauth/token with grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer, the JWT as the assertion, and a Basic Authorization header from the client credentials, receiving a bearer access token (documented example expiry about two hours) plus a refresh token (documented example expiry about seven days); it stores the resulting 'Bearer <token>' value under this reference and refreshes or re-exchanges before expiry.\n\nThe HTTP injector injects the stored value verbatim and performs no OAuth itself — there is no execution-time derivation option. Revocation, according to the reviewed documentation: JWT credentials do not expire unless configured to and can be revoked in the Developer Console by the owner or an administrator, but revoking the JWT stops only new token issuance — already-issued access tokens remain valid until they expire.\n\nRingCentral additionally documents an OAuth revocation mechanism (POST /restapi/oauth/revoke, authenticated with the client credentials, naming the token) that terminates the entire authorization session, invalidating ALL active access and refresh tokens for that session; on suspected exposure the custody job should call it rather than rely on JWT revocation or expiry alone.\n\nLeast privilege: generate the JWT for a dedicated service extension, scope the app to the minimum these capabilities need (read extensions, read messages, read call log, SMS only if the send capability is enabled), and prefer account-level read scopes off unless account-wide visibility is reviewed.\n\nExecutor hygiene: the executor resolves only this reference, so the only RingCentral material it holds is the stored 'Bearer <token>' value. That value must live only in executor memory for the lifetime of a call, must never be written to logs, traces or diagnostics, and must not appear in crash dumps. The JWT and the client secret never reach the executor; the custody job that holds them is subject to the same no-logging and no-crash-dump bar. A deployment that cannot meet that bar must not enable the pack."
  },
  "capabilities": [
    {
      "capability_id": "ringcentral.extensions.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "ringcentral-platform.invalid"
      ],
      "endpoint": "https://ringcentral-platform.invalid/restapi/v1.0/account/ACCOUNT_ID/extension",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-ringcentral-access-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "ringcentral-account",
      "description": "List the account's extensions; this pack registers the collection read only — single-extension reads (GET.../extension/{extensionId}) are not registered. Extension records carry contact first and last names, email addresses and extension numbers, which are personal data, so the read is classified as pii (personal data).\n\nACCOUNT_ID is a placeholder the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "ringcentral.messages.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "ringcentral-platform.invalid"
      ],
      "endpoint": "https://ringcentral-platform.invalid/restapi/v1.0/account/ACCOUNT_ID/extension/EXTENSION_ID/message-store",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-ringcentral-access-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "ringcentral-account",
      "description": "List messages in one extension's unified message store (SMS, fax, pager and voicemail metadata, with the documented filters); this pack registers the collection read only — single-message reads and attachment content (GET.../message-store/{messageId}/content/{attachmentId}) are not registered. Message metadata carries the parties' phone numbers and message subjects, so the read is classified as pii (personal data). By default the endpoint hides messages whose availability is Deleted or Purged; changing that default by query parameter is the caller's choice, not a restriction of this registration.\n\nACCOUNT_ID and EXTENSION_ID are placeholders the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "ringcentral.call_log.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "ringcentral-platform.invalid"
      ],
      "endpoint": "https://ringcentral-platform.invalid/restapi/v1.0/account/ACCOUNT_ID/extension/EXTENSION_ID/call-log",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-ringcentral-access-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "ringcentral-account",
      "description": "List one extension's call log records, with the documented direction, type, view and date-range filters; this pack registers the extension-level collection read only — account-level call log across all extensions (GET.../account/{accountId}/call-log) and call recording content are not registered. Call log records carry phone numbers, names, locations, durations and per-leg call detail, so the read is classified as pii (personal data).\n\nACCOUNT_ID and EXTENSION_ID are placeholders the deployment binds before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "ringcentral.sms.send",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "ringcentral-platform.invalid"
      ],
      "endpoint": "https://ringcentral-platform.invalid/restapi/v1.0/account/ACCOUNT_ID/extension/EXTENSION_ID/sms",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-ringcentral-access-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create",
        "send"
      ],
      "resource_id": "ringcentral-account",
      "description": "Send an SMS from one of the authenticated extension's numbers to one or more recipients. The body permits any destination numbers and message text; enforce further limits separately. RingCentral requires the from number to belong to the authenticated extension, or to be a company number assigned to it for SMS.\n\nPhone numbers and message text are classified as pii (personal data). Registered as create and send at R3 because the operation creates and delivers a message that cannot be recalled.\n\nOn supported AAES-mediated execution paths, send requires approval by an authorized person; this does not prevent calls through bypass or observation-only paths. Bind ACCOUNT_ID and EXTENSION_ID before enabling.",
      "requires_review": true
    },
    {
      "capability_id": "ringcentral.message.delete",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "ringcentral-platform.invalid"
      ],
      "endpoint": "https://ringcentral-platform.invalid/restapi/v1.0/account/ACCOUNT_ID/extension/EXTENSION_ID/message-store/MESSAGE_ID",
      "method": "DELETE",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-ringcentral-access-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "delete"
      ],
      "resource_id": "ringcentral-account",
      "description": "Delete a message from an extension's message store. RingCentral marks it Deleted and allows restoration for a limited period, five days by default. It then purges the content and later removes metadata.\n\nRegistered as delete at R3. The provider's temporary restoration path is separate from AAES approval classification and does not promise recovery in every deployment. On supported AAES-mediated execution paths, delete requires approval by an authorized person; this does not prevent calls through bypass or observation-only paths.\n\nBind ACCOUNT_ID, EXTENSION_ID, and MESSAGE_ID before enabling.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "ringcentral-account",
      "kind": "api",
      "locator": "https://ringcentral-platform.invalid/restapi/v1.0",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-10-22",
    "sources": [
      "https://github.com/ringcentral/ringcentral-api-docs/blob/main/docs/messaging/message-store/messaging.md (retrieved 2026-09-21)",
      "https://github.com/ringcentral/ringcentral-api-docs/blob/main/docs/authentication/jwt-flow.md (retrieved 2026-09-21)",
      "https://raw.githubusercontent.com/ringcentral/ringcentral-api-docs/main/docs/authentication/tokens.md (retrieved 2026-09-21)",
      "https://raw.githubusercontent.com/ringcentral/ringcentral-api-docs/main/docs/account/extensions.md (retrieved 2026-09-21)",
      "https://raw.githubusercontent.com/ringcentral/ringcentral-api-docs/main/docs/messaging/sms/sending-sms.md (retrieved 2026-09-21)",
      "https://raw.githubusercontent.com/ringcentral/ringcentral-api-docs/main/docs/voice/call-log/api.md (retrieved 2026-09-21)"
    ],
    "reviewer_id": "owner-delegated"
  }
}
