Skip to content

Commit 96399fe

Browse files
committed
Small adjustments
Signed-off-by: peterdeme <[email protected]>
1 parent bb8ee7e commit 96399fe

File tree

6 files changed

+307
-224
lines changed

6 files changed

+307
-224
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ For more complex contributions, we recommend that you open an issue to describe
1818
- Start a free trial at https://spacelift.io/free-trial.
1919
<!-- markdownlint-enable MD001 MD034 -->
2020

21+
## Miscellaneous
22+
2123
## License
2224

2325
The Spacelift user documentation is licensed under the [MIT license](./LICENSE).

docs/concepts/authorization/assigning-roles-stacks.md

Lines changed: 77 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Stack role attachments
1+
# Stack role bindings
22

33
Stacks can receive role bindings to perform operations with elevated permissions, similar to how users, API keys, and IdP groups receive permissions through [Spacelift's RBAC system](rbac-system.md).
44

@@ -32,9 +32,9 @@ This means a stack can create contexts and worker pools, but cannot manage any o
3232

3333
**Administrative flag**: Basic audit trail with stack actor information.
3434

35-
**Role attachments advantage**: Audit trail webhooks include role information in the `ActorRoles` field (array of role slugs).
35+
**Role attachments advantage**: Audit trail webhooks include role information in the `actor_roles` field (array of role slugs).
3636

37-
This provides better visibility into what permissions the stack was using when performing actions. See the [audit trail documentation](../../integrations/audit-trail.md) for details.
37+
This provides better visibility into what permissions the stack was using when performing actions. See the [audit trail documentation](../../integrations/audit-trail.md#usage) for details.
3838

3939
### Modern RBAC consistency
4040

@@ -46,8 +46,8 @@ Role attachments align stacks with the broader role-based access model already u
4646

4747
To attach a role to a stack, you need:
4848

49-
- `StackManage` permission (or `SpaceAdmin` permission as fallback) to the stack's space
50-
- `SpaceAdmin` permission to the binding space (the space where the role will be effective)
49+
- `StackManage` [permission](./rbac-system.md#actions-the-building-blocks-of-permissions) (or Space admin permission as fallback) to the stack's space
50+
- Space admin permission to the binding space (the space where the role will be effective)
5151

5252
!!! info "Why both permissions are required"
5353
Creating a role binding that grants permissions to a space effectively allows the stack to act in that space. To prevent privilege escalation, you must have admin access to both spaces: the space where the stack resides and the space where the role will be effective.
@@ -64,49 +64,78 @@ To attach a role to a stack, you need:
6464
Use the `spacelift_role_attachment` resource:
6565

6666
```hcl
67-
resource "spacelift_stack" "admin" {
68-
name = "Admin stack"
69-
repository = "spacelift-resources"
67+
resource "spacelift_space" "devops" {
68+
name = "devops"
69+
description = "A space for devops engineers"
70+
parent_space_id = "root"
71+
}
72+
73+
resource "spacelift_stack" "devops_admin" {
74+
name = "Admin stacks for Devs"
75+
repository = "spacelift-dev-resources"
76+
space_id = spacelift_space.devops.id
7077
description = "Only has permissions to create another stacks in the dev space"
78+
repository = "stacks-for-devs"
7179
branch = "main"
7280
}
7381
7482
resource "spacelift_role" "stack_creator" {
7583
name = "Stack creator"
76-
description = "A role solely for creating stacks"
84+
description = "A role solely for managing stacks"
7785
actions = ["STACK_MANAGE"]
7886
}
7987
8088
resource "spacelift_space" "dev" {
8189
name = "dev"
90+
description = "A space for development stacks"
8291
parent_space_id = "root"
8392
}
8493
85-
resource "spacelift_role_attachment" "stack_creator_to_admin_stack" {
86-
stack_id = spacelift_stack.admin.id
87-
role_id = spacelift_role.stack_creator.id
88-
space_id = spacelift_space.dev.id
94+
resource "spacelift_role_attachment" "stack_creator_to_devops_admin_stack" {
95+
stack_id = spacelift_stack.devops_admin.id # (1)
96+
role_id = spacelift_role.stack_creator.id # (2)
97+
space_id = spacelift_space.dev.id # (3)
8998
}
9099
```
91100

101+
1. The stack receiving the role attachment.
102+
2. The [role](./rbac-system.md#roles) to attach to the stack.
103+
3. The target space: this is where the role will be effective.
104+
105+
In the above scenario, the `devops_admin` stack will have the `Stack creator` role effective in the `dev` space, allowing it to create and manage stacks within that space.
106+
92107
For more information, see the [Spacelift Terraform provider documentation](https://search.opentofu.org/provider/spacelift-io/spacelift/latest/docs/resources/role_attachment){: rel="nofollow"}.
93108

94109
## Permission cascading
95110

96111
Role attachments cascade down to child spaces, similar to how the administrative flag worked:
97112

98-
```text
99-
parentSpace
100-
├── childSpace1
101-
└── childSpace2
102-
└── grandchildSpace
113+
```mermaid
114+
graph TD
115+
role{{Role}}
116+
parentSpace[ParentSpace]
117+
childSpace1[ChildSpace1]
118+
childSpace2[ChildSpace2]
119+
grandchildSpace[GrandchildSpace]
120+
121+
role ~~~ parentSpace
122+
role e1@-. Attached to .-> parentSpace
123+
e1@{animate: true}
124+
parentSpace --> childSpace1
125+
parentSpace --> childSpace2
126+
childSpace2 --> grandchildSpace
103127
```
104128

105-
If a role is attached to `parentSpace`, the same role will be effective in `childSpace1`, `childSpace2`, and `grandchildSpace`.
129+
If a role is attached to `ParentSpace`, the same role will be effective in `ChildSpace1`, `ChildSpace2`, and `GrandchildSpace` as well.
106130

107-
!!! warning "Root space caution"
131+
!!! danger "Root space caution"
108132
Since the `root` space is the parent of all spaces, attaching roles to it affects **all spaces** in your account. Use this with extreme caution and only when necessary.
109133

134+
### Root space restriction
135+
136+
You can only assign a role to the `root` space if the stack itself is located in the `root` space. This restriction prevents unintentional access elevation - a stack in a _child-of-root_ space cannot be granted permissions that cascade to all spaces in your account.
137+
If you need a stack in a child space to access resources across multiple spaces, attach roles to specific spaces rather than the root space.
138+
110139
## Administrative flag precedence
111140

112141
The administrative flag takes precedence over role attachments:
@@ -126,10 +155,12 @@ package spacelift
126155
127156
reject_with_note["Don't use the Space Admin role!"] {
128157
role := input.stack.roles[_]
129-
role.id == "space-admin" # Role slug. Use the "Copy Slug" button in the UI to get it.
158+
role.id == "space-admin" # (1)
130159
}
131160
```
132161

162+
1. Role slug. Use either "Copy Slug" button in the UI or the [`spacelift_role` data source](https://search.opentofu.org/provider/spacelift-io/spacelift/latest/docs/datasources/role){: rel="nofollow"} to retrieve it.
163+
133164
## Multiple roles
134165

135166
Stacks can have multiple role bindings:
@@ -158,13 +189,17 @@ resource "spacelift_role_attachment" "prod_reader" {
158189

159190
## External state access
160191

161-
External state access allows you to read the state of the stack from outside authorized runs and [tasks](../../concepts/run/task.md). See the documentation [here](../../vendors/terraform/external-state-access.md) for further details.
192+
External state access allows you to read the state of a stack from outside authorized runs and tasks. See the documentation [here](../../vendors/terraform/external-state-access.md) for further details.
162193

163194
In order for your stack to access another stack's OpenTofu/Terraform state, the stack needs to have **Space writer** role to the target stack's space. This can be achieved by attaching the **Space writer** role to the stack for the target stack's space.
164195

165196
Example:
166197

167198
```hcl
199+
resource "spacelift_stack" "consumer" {
200+
# Properties are omitted for brevity
201+
}
202+
168203
data "spacelift_role" "space_writer" {
169204
slug = "space-writer"
170205
}
@@ -174,17 +209,24 @@ resource "spacelift_role_attachment" "space_writer" {
174209
role_id = data.spacelift_role.space_writer.id
175210
space_id = spacelift_stack.provider.space_id
176211
}
212+
213+
resource "spacelift_stack" "provider" {
214+
# Properties are omitted for brevity
215+
terraform_external_state_access = true
216+
}
177217
```
178218

179219
!!! note
180-
The **Space admin** role also includes **Space writer** permissions.
220+
The Space admin role also includes Space writer permissions.
181221

182222
## Migration from administrative flag
183223

184-
!!! warning "Automatic Migration on June 1st, 2026"
185-
On June 1st, 2026, Spacelift will automatically disable all administrative flags and attach the Space Admin role to each stack's own space. This automatic migration is **100% backward compatible** and ensures no functionality loss.
224+
On June 1st, 2026, Spacelift will automatically disable all administrative flags and attach the Space Admin role to each stack's own space. This automatic migration is **100% backward compatible** and ensures no functionality loss.
186225

187-
However, **manual migration is strongly recommended** to take advantage of advanced features like cross-space access and fine-grained permissions that are not available with automatic migration.
226+
However, **manual migration is strongly recommended** to avoid breaking the OpenTofu/Terraform state: since the administrative flag will be disabled during this process, the stacks will experience a drift. The administrative flag will be ineffective (even if set to true, it'll return false), so the only solution to reconcile will be to attach the Space Admin role to the stack's own space.
227+
228+
!!! note
229+
The Space admin role is a built-in system role so you don't need to create it manually, it already exists in your Spacelift account.
188230

189231
### What happens on June 1st, 2026
190232

@@ -231,19 +273,19 @@ Assuming your stack is in the `dev` [Space](../spaces/README.md), the role attac
231273

232274
![](../../assets/screenshots/role_stacks_migration.png)
233275

234-
#### 3. Disable the administrative flag
276+
#### 3. Remove the administrative attribute
235277

236-
Once you've verified the roles have been attached, disable the administrative flag:
278+
Once you've verified the roles have been attached, remove the administrative attibute:
237279

238-
```hcl
280+
```diff
239281
resource "spacelift_stack" "management" {
240-
# [... other stack settings ...]
241-
administrative = false
282+
name = "Management Stack"
283+
- administrative = true
242284
}
243285
```
244286

245287
!!! important
246-
The administrative flag takes precedence over role attachments. If `administrative = true`, any attached roles will be ignored. You must set `administrative = false` for role attachments to take effect.
288+
The administrative flag takes precedence over role attachments. If `administrative = true`, any attached roles will be ignored. You must either set `administrative = false`, or entirely remove the administrative attribute (recommended) for role attachments to take effect.
247289

248290
#### 4. Verify the role attachment
249291

@@ -263,10 +305,12 @@ deny_with_note["Administrative stacks are not allowed"] {
263305
# Would become:
264306
deny_with_note["Administrative stacks are not allowed"] {
265307
role := input.stack.roles[_]
266-
role.id == "space-admin" # Role slug. Use the "Copy Slug" button in the UI to get it.
308+
role.id == "space-admin" # (1)
267309
}
268310
```
269311

312+
1. Role slug. Use either "Copy Slug" button in the UI or the [`spacelift_role` data source](https://search.opentofu.org/provider/spacelift-io/spacelift/latest/docs/datasources/role){: rel="nofollow"} to retrieve it.
313+
270314
### Rollback procedure
271315

272316
If you need to roll back during migration:

docs/concepts/authorization/rbac-system.md

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -185,17 +185,28 @@ All RBAC roles are **space-bound**, meaning:
185185

186186
Spaces can be organized hierarchically to reflect your organizational structure:
187187

188-
```text
189-
Root Space
190-
├── Infrastructure (Platform team management)
191-
│ ├── Networking
192-
│ ├── Security
193-
│ └── Monitoring
194-
├── Applications (Application teams)
195-
│ ├── Frontend
196-
│ ├── Backend
197-
│ └── Mobile
198-
└── Sandbox (Development and testing)
188+
```mermaid
189+
graph TD
190+
Root["Root Space"]
191+
Infrastructure["Infrastructure<br/>(Platform team management)"]
192+
Networking[Networking]
193+
Security[Security]
194+
Monitoring[Monitoring]
195+
Applications["Applications<br/>(Application teams)"]
196+
Frontend[Frontend]
197+
Backend[Backend]
198+
Mobile[Mobile]
199+
Sandbox["Sandbox<br/>(Development and testing)"]
200+
201+
Root --> Infrastructure
202+
Root --> Applications
203+
Root --> Sandbox
204+
Infrastructure --> Networking
205+
Infrastructure --> Security
206+
Infrastructure --> Monitoring
207+
Applications --> Frontend
208+
Applications --> Backend
209+
Applications --> Mobile
199210
```
200211

201212
#### Space design patterns

0 commit comments

Comments
 (0)