{
  "schema": "aaes/capability-pack/1",
  "provider": "slack",
  "version": "1.1.0",
  "description": "Slack: read channels and message history, post messages and add reactions as a bot, and create public file links with a separate user token.",
  "credential": {
    "secret_ref_id": "secret-ref-slack-bot-token",
    "custody": "customer_vault",
    "inject": "header",
    "inject_name": "Authorization",
    "note": "Slack API tokens held in the client's own secret manager. The stored material under any of this pack's references must be the complete Authorization header value (scheme included), never just the token. The package contains references, not token values. The executor resolves those references when making a call. This pack-level reference, secret-ref-slack-bot-token, binds the four bot capabilities (slack.conversations.list, slack.conversations.history, slack.chat.postMessage, slack.reactions.add): the stored value is a Slack bot token, and the bot scopes are a starting point — review them against the channels this workspace actually needs before enabling. slack.files.share is deliberately bound differently: it carries its own per-capability credential reference, secret-ref-slack-user-token, because Slack documents files.sharedPublicURL for user tokens only (User token: files:write, with no bot-token row).\n\nThe stored value under the user-token reference must be a Slack user token bearing files:write, minted and stored by an external deployment process; the two references are not interchangeable, and enabling slack.files.share requires the user-token reference to be populated separately from the pack-level bot-token reference."
  },
  "capabilities": [
    {
      "capability_id": "slack.conversations.list",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "slack.com"
      ],
      "endpoint": "https://slack.com/api/conversations.list",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-slack-bot-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "slack-workspace",
      "description": "List the channels in the workspace the bot can see.",
      "requires_review": true
    },
    {
      "capability_id": "slack.conversations.history",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R0",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "slack.com"
      ],
      "endpoint": "https://slack.com/api/conversations.history",
      "method": "GET",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-slack-bot-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "read"
      ],
      "resource_id": "slack-workspace",
      "description": "Read message history from one channel; messages routinely contain personal data, so the read is classified as pii (personal data).",
      "requires_review": true
    },
    {
      "capability_id": "slack.chat.postMessage",
      "version": "1.1.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "slack.com"
      ],
      "endpoint": "https://slack.com/api/chat.postMessage",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-slack-bot-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "send"
      ],
      "resource_id": "slack-workspace",
      "description": "Post a message to a channel. A message cannot be recalled after delivery, and send is one of the designated actions requiring human approval, which is why it carries the minimum R3 tier. The message lands in a channel whose history this pack classifies pii, and Slack's formatting documentation lets message text mention users by id (<@U…>), which Slack renders as the user's display name, so the capability is classified pii (personal data), the same class as the slack-workspace resource.",
      "requires_review": true
    },
    {
      "capability_id": "slack.files.share",
      "version": "1.1.0",
      "kind": "tool",
      "risk_tier": "R3",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "pii",
      "egress_allowlist": [
        "slack.com"
      ],
      "endpoint": "https://slack.com/api/files.sharedPublicURL",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-slack-user-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "share"
      ],
      "resource_id": "slack-workspace",
      "description": "Create a public sharing link for a file uploaded to the workspace. Revoking a link cannot undo disclosure to people who already accessed it. Registered as share at R3. Slack documents that the returned file object names the uploading user (the user field), and the shared file's content is caller-chosen, so the capability is classified pii (personal data), the same class as the slack-workspace resource.\n\nSlack documents files.sharedPublicURL for user tokens with files:write, with no bot-token entry. This capability therefore uses secret-ref-slack-user-token, separate from the package's bot-token reference. Store a user token with files:write under that reference; the references are not interchangeable. See the credential note for the header contract.",
      "requires_review": true
    },
    {
      "capability_id": "slack.reactions.add",
      "version": "1.0.0",
      "kind": "tool",
      "risk_tier": "R2",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN",
      "data_class": "internal",
      "egress_allowlist": [
        "slack.com"
      ],
      "endpoint": "https://slack.com/api/reactions.add",
      "method": "POST",
      "connector": "http",
      "custody": "customer_vault",
      "secret_ref_id": "secret-ref-slack-bot-token",
      "inject": "header",
      "inject_name": "Authorization",
      "actions": [
        "create"
      ],
      "resource_id": "slack-workspace",
      "description": "Add an emoji reaction to a message.",
      "requires_review": true
    }
  ],
  "resources": [
    {
      "resource_id": "slack-workspace",
      "kind": "channel",
      "locator": "slack://workspace/REPLACE-WITH-WORKSPACE-ID",
      "data_class": "pii",
      "owner": "REPLACE-WITH-ACCOUNTABLE-HUMAN"
    }
  ],
  "review": {
    "state": "library",
    "date": "2026-10-22",
    "sources": [
      "https://docs.slack.dev/reference/methods/chat.postMessage (retrieved 2026-09-20)",
      "https://docs.slack.dev/reference/methods/conversations.history (retrieved 2026-09-20)",
      "https://docs.slack.dev/reference/methods/files.sharedPublicURL (retrieved 2026-09-20)",
      "https://docs.slack.dev/changelog (retrieved 2026-09-20)",
      "https://docs.slack.dev/reference/methods/conversations.list (retrieved 2026-09-23)",
      "https://docs.slack.dev/reference/methods/reactions.add (retrieved 2026-09-23)"
    ],
    "reviewer_id": "owner-delegated"
  },
  "notes": "This pack registers five Slack Web API methods on slack.com/api, each checked against Slack's method reference: conversations.list (GET; channels:read covers the default public_channel type, and private channels, DMs and group DMs are listed only when the token also has groups:read, im:read or mpim:read), conversations.history (GET; the *:history scope for the conversation type), chat.postMessage (POST; chat:write, plus chat:write.public to post in public channels the bot has not joined), reactions.add (POST; reactions:write) and files.sharedPublicURL (POST; a user token with files:write). Grant only the scopes for the conversation types and capabilities you enable.\n\nApproval classification: the two reads sit at the minimum R0 tier; adding a reaction is create at the minimum R2 tier; posting a message is send at the minimum R3 tier, because Slack's chat.delete can remove a message but cannot undo the fact that people have read it; creating a public file link is share at the minimum R3 tier. Slack documents that only the file's creator can make a file public unless it has been shared into a public channel, and a workspace can disable public file sharing.\n\nData classes: message history, message posting and public file links are classified pii (personal data), matching the workspace resource: posted text can mention users by id and lands in channels whose history is personal data, and a shared file object names its uploader. The channel list and reaction capabilities are registered internal. Pack version 1.1.0 moved the message-post and file-link capabilities from internal to pii; a capability's version is the pack version in which its registration last changed.\n\nExclusions: this pack does not register message update or deletion (chat.update, chat.delete), file upload or file deletion, reactions.remove, revoking a public file link, user and profile reads, channel creation, joining, archiving or membership changes, admin and SCIM APIs, the Events API and Socket Mode. The bot-token and user-token references are not interchangeable; see the credential note.\n\nAAES has not been certified by Slack; the endpoints here are configuration to review and test; the vendor has not endorsed it."
}
