Why can't my Slack channel subscribe to stacks in certain spaces using /spacelift subscribe?
Last updated: November 3, 2026
It's recommended to instead use the notification policy in order to manage slack messages received from Spacelift. These slash commands are deprecated.
Also, please note that slash commands only work if your Spacelift instance is publicly accessible by Slack. If your Spacelift installation uses an internal load balancer, for example, slash commands will not work.
Context
When using the /spacelift subscribe slash command to subscribe a Slack channel to stack notifications, the command may succeed for stacks in some spaces (e.g., legacy) but fail for stacks in others (e.g., child spaces like runtime). This is typically a LOGIN policy configuration issue related to how Spacelift evaluates multiple policies together.
Answer
The /spacelift subscribe command is purely RBAC-driven. For it to work, the Slack session must:
Be allowed by the LOGIN policy evaluation (i.e., at least one policy must produce an
allowdecision and no policy must produce adeny).Have a space role (e.g.,
space-reader) granted on a space that is a parent of the target stack's space.
Important: If you have multiple LOGIN policies, Spacelift merges them all together. If any policy results in a deny, or if none of them produce an allow for the Slack session, the overall decision is deny. This means a deny { not allow; not admin } rule in one policy will reject the Slack session if no other policy in the set explicitly allows it.
A common root cause is having a catch-all deny rule in one LOGIN policy (e.g., deny { not allow; not admin }) while the allow rule for Slack sessions lives in a separate policy. Because policies are evaluated together, the deny fires before the Slack-specific allow can take effect.
To fix this, ensure that the policy containing the catch-all deny rule also includes an explicit allow rule for Slack sessions. For example, add the following to the same policy that contains your deny rule:
allow {
input.slack.team.id == "<your-slack-workspace-id>"
}This ensures the Slack session is not rejected before the space-reader role assignment (defined in another policy) can take effect.
Additionally, to grant a Slack channel access to stacks across all spaces (including child spaces), assign the space-reader role on the root space in your LOGIN policy. Because root is inherited by all child spaces, this allows the channel to subscribe to stack notifications across your entire space hierarchy:
roles["root"]["space-reader"] {
input.slack.team.id == "<your-slack-workspace-id>"
}