{
  "schema": "aaes/capability-pack/1",
  "provider": "zendesk",
  "version": "1.0.0",
  "description": "Zendesk Support: read tickets, users and organizations, and create or update tickets whose public comments reach customers.",
  "notes": "The endpoint host 'your-org.zendesk.invalid' is a reserved non-production placeholder (.invalid is an RFC 2606 reserved TLD that can never resolve): substitute the account's own Zendesk subdomain host (your-subdomain.zendesk.com — the documented Zendesk API subdomain for the account; this review found no Zendesk documentation supporting host-mapped support domains as an interchangeable API destination, so none is offered) before enabling, in the endpoints, the resource locators and the egress allowlist — the allowlist matches exactly, so all three must be substituted together, and substitution is a required pre-enablement step.\n\nNote that allowlisting the reserved placeholder host does NOT make an unsubstituted pack safe: an unsubstituted pack has never been bound to the account it claims to govern, and its review says nothing about that account. This pack registers only endpoints the official Zendesk Ticketing API reference documents: the tickets, users and organizations collection reads, single-ticket creation and single-ticket update. All read capabilities cover the COLLECTION read only: single-record reads (GET /api/v2/tickets/{ticket_id}, /api/v2/users/{user_id}, /api/v2/organizations/{organization_id}), show_many, search, autocomplete, counts and incremental exports are not registered by this pack.\n\nConsequential effects: a ticket create sets the ticket's first comment, and a ticket update can add a comment; Zendesk documents that end users can see public comments, that collaborators receive email notifications when tickets are updated, and that tickets created through the API may trigger business rules that send email notifications to end users — so the unrestricted effect of both write operations includes transmitting to the customer, and both declare send at the minimum R3 tier alongside create/update. send is one of the designated actions requiring human approval: a public reply cannot be recalled after delivery.\n\nAn internal-note-only ticket create or update (comment with public=false) is NOT registered: the public flag is a request-body property of the same POST/PUT endpoint, and a pack registers an endpoint, not a body value, so nothing in the registration would enforce the note-only restriction; an R2 note-only capability requires a separately reviewed adapter that enforces public=false.\n\nDocumented exclusions: this pack does not register ticket delete, bulk delete or permanent delete, ticket merge, mark-as-spam (which suspends the requester), user create/update/delete or merge, organization create/update/delete or merge, the Requests API, side conversations, and satisfaction-rating writes — an excluded operation.\n\nData-class rationale: tickets and users identify individuals and carry their correspondence, so both are pii; organizations describe customer companies (names, domains, notes) and are registered internal. The endpoints are verified against the provider documents named in the review block, and credential custody was reviewed on 2026-09-21 against this pack's custody model (an account-level API token used as HTTP Basic credentials, held in the customer's vault), with the following findings.\n\nIssuance authority and delegation: an admin enables API token access in the Zendesk Admin Center (Apps and integrations > APIs > Zendesk API) and adds tokens, so issuance authority sits with the account's own admin; the token is an account-level credential while the '{email_address}/token' prefix selects which user each request authenticates AS — Zendesk warns that, as passwords, API tokens can be used to impersonate anyone in the account, including admins.\n\nScope: Zendesk documents no per-token scoping — the token inherits the prefixed user's full permissions, so least privilege pairs the token with a dedicated service account whose role covers exactly the registered capabilities; Zendesk marks API tokens deprecated and directs migration to OAuth, which remains the stronger option where the deployment supports it. Audience: no audience mechanism is documented — the Basic credential authorizes against the account's zendesk.com subdomain, and audience binding beyond that is not established. TTL: the retrieved security-and-auth documentation states no expiry behavior for API tokens either way, so the completed review documents none: treat the token as live until it is deleted.\n\nRefresh ownership: there is no refresh — the token IS the credential and no tokens are derived from it; the executor injects the stored value verbatim and performs no token lifecycle itself.\n\nRevocation: deleting the token in the Admin Center deactivates it permanently; deactivating or deleting the prefixed user prevents authentication AS that user but does not necessarily revoke the account-level value for other eligible users, and deleting this API token does not revoke already-issued OAuth tokens, which must be revoked separately. Executor access and replay/exposure: the executor reads only the vault reference; the credential is replayable with no documented TTL bound until deleted, and more than one token can be active at the same time (up to the documented 256-token limit), so the account's token inventory is reviewed before enabling.\n\nAlternate access paths: the Zendesk UI, OAuth clients and the account's other API tokens retain access outside this pack, and deleting this token closes only this path. Credential custody review is complete. Bind the remaining owner placeholders before deployment.",
  "credential": {
    "secret_ref_id": "secret-ref-zendesk-api-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "A Zendesk API token used as HTTP Basic credentials, held in the client's own secret manager. The stored material must be the complete Authorization header value: the scheme 'Basic', one separating space, then the Base64 encoding of '{email_address}/token:{api_token}' exactly as Zendesk's API reference shows — 'Basic <base64>'. Token issuance is an external process: an admin enables API token access in the Zendesk Admin Center (Apps and integrations > APIs > Zendesk API) and adds a token; the executor performs no token lifecycle itself and injects the stored value verbatim.\n\nNote that Zendesk's own security documentation marks API tokens deprecated and directs existing basic-authentication/API-token customers to migrate to OAuth access tokens; where the deployment supports it, prefer OAuth. Custody boundary — account-level token, user-selected identity: an API token is an account-level credential managed in the Admin Center (the page lets an admin view, add or delete tokens, and more than one token can be active at the same time), while the '{email_address}/token' prefix selects which user the request authenticates AS — Zendesk warns that, as passwords, API tokens can be used to impersonate anyone in the account, including admins.\n\nDeactivating or deleting the user whose email prefixes the token prevents authentication AS that user, but does not necessarily revoke the account-level token value for other eligible users: deleting the token in the Admin Center revokes the value itself, and Zendesk documents that deleting a token deactivates it permanently.\n\nLeast privilege: the token authenticates AS the user whose email prefixes it and inherits that user's full permissions, so pair the token with a dedicated least-privilege service account whose role covers exactly the registered capabilities. Expiry: Zendesk's retrieved security-and-auth documentation states no expiry behavior for API tokens either way, so none is asserted here — treat the token as live until it is deleted in the Admin Center (deletion deactivates it permanently) or the account's auth posture otherwise changes.\n\nBoundary: if the deployment also runs OAuth against the same account, deleting this API token (or the OAuth client) does NOT revoke already-issued OAuth access or refresh tokens, which must be revoked separately. OAuth 2.0 with scoped access tokens is the stronger option where the deployment supports it; review the owning account's role and token inventory before enabling.\n\nExecutor hygiene: the 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; a deployment that cannot meet that bar must not enable the pack."
  },
  "capabilities": [
    {
      "capability_id": "zendesk.tickets.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "your-org.zendesk.invalid"
      ],
      "endpoint": "https://your-org.zendesk.invalid/api/v2/tickets",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-zendesk-api-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "zendesk-account-tickets",
      "description": "List tickets: subjects, statuses, requester and assignee ids, tags and the first comment (the description property), which identify individuals and carry their correspondence. The registered path covers the collection read only — single-ticket reads (GET /api/v2/tickets/{ticket_id}), show_many, comment listing, counts and incremental exports are not registered by this pack.",
      "requires_review": true
    },
    {
      "capability_id": "zendesk.users.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "your-org.zendesk.invalid"
      ],
      "endpoint": "https://your-org.zendesk.invalid/api/v2/users",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-zendesk-api-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "zendesk-account-users",
      "description": "List users (end users, agents and admins): names, email addresses, phone numbers, roles and organization memberships, which are personal data. The registered path covers the collection read only — single-user reads (GET /api/v2/users/{user_id}), user search and autocomplete are not registered by this pack.",
      "requires_review": true
    },
    {
      "capability_id": "zendesk.organizations.read",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "your-org.zendesk.invalid"
      ],
      "endpoint": "https://your-org.zendesk.invalid/api/v2/organizations",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-zendesk-api-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "zendesk-account-organizations",
      "description": "List organizations: names, domain names, notes and custom fields, which describe customer companies and are registered internal. The registered path covers the collection read only — single-organization reads (GET /api/v2/organizations/{organization_id}), search and autocomplete are not registered by this pack.",
      "requires_review": true
    },
    {
      "capability_id": "zendesk.tickets.create",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "your-org.zendesk.invalid"
      ],
      "endpoint": "https://your-org.zendesk.invalid/api/v2/tickets",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-zendesk-api-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create",
        "send"
      ],
      "resource_id": "zendesk-account-tickets",
      "description": "Create one ticket; the request's comment object becomes the ticket's first comment. The declared effect includes send at the minimum R3 tier: a public first comment is visible to the end user, collaborators added at creation are sent an email notification, and Zendesk documents that tickets created via the API may trigger business rules that send email notifications to end users — so creating a ticket can transmit to the customer, and a sent message cannot be recalled after delivery. send is one of the designated actions requiring human approval.\n\nOn supported AAES-mediated execution paths, irreversible actions require approval by an authorized person; this does not prevent calls through bypass or observation-only paths. An internal-note-only variant is deliberately not registered: the public flag is a request-body property of this same endpoint, so the registration cannot enforce it.",
      "requires_review": true
    },
    {
      "capability_id": "zendesk.tickets.update",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "your-org.zendesk.invalid"
      ],
      "endpoint": "https://your-org.zendesk.invalid/api/v2/tickets/TICKET_ID",
      "method": "PUT",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-zendesk-api-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "update",
        "send"
      ],
      "resource_id": "zendesk-account-tickets",
      "description": "Update one ticket, including status, assignee, fields and an added comment. The declared effect includes send at the minimum R3 tier: a public comment added by an update is visible to the end user, and Zendesk documents that collaborators receive email notifications when tickets are updated — so an update can transmit to the customer, and a sent message cannot be recalled after delivery. send is one of the designated actions requiring human approval.\n\nAn internal-note-only variant is deliberately not registered: the public flag is a request-body property of this same endpoint, so the registration cannot enforce it. TICKET_ID is a placeholder the deployment binds to a concrete ticket before enabling.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "zendesk-account-tickets",
      "kind": "api",
      "locator": "https://your-org.zendesk.invalid/api/v2/tickets",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "zendesk-account-users",
      "kind": "api",
      "locator": "https://your-org.zendesk.invalid/api/v2/users",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    },
    {
      "resource_id": "zendesk-account-organizations",
      "kind": "api",
      "locator": "https://your-org.zendesk.invalid/api/v2/organizations",
      "data_class": "internal",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-09-22",
    "sources": [
      "https://developer.zendesk.com/api-reference/ticketing/tickets/tickets/ (retrieved 2026-09-21)",
      "https://developer.zendesk.com/api-reference/ticketing/users/users/ (retrieved 2026-09-21)",
      "https://developer.zendesk.com/api-reference/ticketing/organizations/organizations/ (retrieved 2026-09-21)",
      "https://developer.zendesk.com/api-reference/introduction/security-and-auth/ (retrieved 2026-09-21)"
    ],
    "reviewer_id": "aaes-eng"
  }
}
