Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Custom Roles: Users with Limited Permissions Can Still Create Workspaces #16546

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
rogmanster opened this issue Feb 12, 2025 · 7 comments
Closed
Assignees
Labels
multi-org temporary label for multiple organizations related work

Comments

@rogmanster
Copy link
Contributor

Users with Limited Permissions Can Still Create Workspaces

Description

We are attempting to create a restricted role where users are unable to create or edit workspaces. This role should function similarly to the Platform Member role described in the Coder documentation.

However, when testing, users assigned this custom role were still able to create workspaces, which is unexpected behavior.

Steps to Reproduce

  1. Created a custom role.
  2. Assigned only the workspace:application_connect permission.
  3. Assigned this role to a user in the default organization.
  4. Logged in as the user and observed that they were still able to create a workspace.

Expected Behavior

The user should not have the ability to create a workspace, given that they only have the workspace:application_connect permission.

Actual Behavior

The user was still able to create a new workspace despite lacking explicit permissions for workspace creation.

Environment

  • Coder Version: 2.18.5
  • Deployment Method: Helm
  • Organization Settings: Default

Additional Context

We would like to clarify whether additional permissions are implicitly granting workspace creation or if this is a bug. If additional restrictions are needed to prevent workspace creation, please advise on the correct role configuration.

Possible Workarounds

N/A at this time.

Would appreciate any guidance on resolving this issue! 🚀

@Emyrk
Copy link
Member

Emyrk commented Feb 13, 2025

Explanation of what is happening

There is 2 things at play here allowing a user to make a workspace with their member role alone. To create a workspace you need the create permission for the workspace, and the use permission for the selected template.

The use permission is likely inherited from the Everyone group. When making a new template, it has this ACL permission on it.

Image

The create permission is sourced from something a bit more nuanced. There is a truth table that explains how the hierarchical permissions work here: https://github.com/coder/coder/tree/main/coderd/rbac#roles

In short, for this situation, the create authz call looks something like:

{
  "action": "create",
  "object": {
     "id":"b1d759e4-d698-462b-bb10-d4f4e0761289",
     "owner":"a4f14310-d82b-49f8-b971-0a81c63adac2",
     "org_owner":"f4b6b219-36f6-4dc7-b306-201cb990949b",
     "type":"workspace",
  }
}

The two possible states are the user is not in the org, or the user is in the org.

Action Site Org User Result
not-in-org _ N Y N
member-of-org _ _ Y Y

As it stands today, the organization has no opinion on if a user should be able to create a workspace because the user owns the workspace. So the permission checks assumes the user is trying to create a resource for themselves. Rather than creating an organization resource.

This feels like a mistake, see the solution proposed to fix this.

Solution ideas

1. Creating a workspace should be an org permission check (Recommended, just need to figure out UX) Then a user with create perms can create a workspace for any user in an org.

We could remove the owner id from the authz check when creating a workspace. This would mean the user needs explicit create permission to create a workspace for a given org.

The question still exists, "Should members have this permission". And, "How do we make a member without this permissions?".

Action Site Org User Result
member-of-org _ Y _ Y

Once the workspace is created, then it can be assumed to be owned by the Org and the User.

2. Create a negative permission to disallow the action

Our rbac system allows for negative permissions (not used in our roles yet). We could allow a custom role that disallows create.workspace. That would block a user from making workspaces, leaving the current roles unchanged.

Action Site Org User Result
negative-permission _ N Y N

3: Revoke all permissions from the "member" site & org role.

Trim member roles to revoke workspace permissions. Create a new role creator (name tbd), and assign the workspace create permission to that new revokable role.

Run a migration to assign all users this new role.

The downside is now all users have 2 "implied" roles effectively, as most users will not have their second role revoked. Maybe orgs have to have some "default-roles" assigned at member create?

The problem is the current architecture always assumes the user has some implied role. Because the policy engine needs some role to deduce the user belongs in an organization.

So another option is to have 2 kinds of implied roles, but that logic feels difficult to maintain. Implied roles are a nuisance enough as it is.

@matifali matifali added multi-org temporary label for multiple organizations related work and removed needs-triage Issue that require triage labels Feb 13, 2025
@aslilac
Copy link
Member

aslilac commented Feb 13, 2025

imho, the easiest fix for this is to make "member" a revokable role that's only given by default

@Emyrk
Copy link
Member

Emyrk commented Feb 13, 2025

@aslilac I think there has to be some implied member role for an organization. The rego policy uses that role to know the user is in an organization, or not. Since org membership is a Coder concept independent of roles.

So maybe there exists some 0 permission ed implied role 🤔

@aslilac
Copy link
Member

aslilac commented Feb 13, 2025

so we need to take permissions away from the built-in "member" roles and add a new one that gives permissions like creating a workspace

if it only gives workspace creation, it could be called "workspace user" or something, but I can't really think of any obvious name for a more general role that solves this problem.

@Emyrk
Copy link
Member

Emyrk commented Feb 20, 2025

Solution 2, called WorkspaceCreationBan that can be assigned at the org level. This would be a new builtin role assignable at the org level.

The role should be less visible than other roles. A primitive example

Image

Docs need to accompany this new role.

@Emyrk Emyrk self-assigned this Feb 20, 2025
jaaydenh added a commit that referenced this issue Feb 27, 2025
Using negative permissions, this role prevents a user's ability to
create & delete a workspace within a given organization.

Workspaces are uniquely owned by an org and a user, so the org has to
supercede the user permission with a negative permission.

# Use case

Organizations must be able to restrict a member's ability to create a
workspace. This permission is implicitly granted (see
#16546 (comment)).

To revoke this permission, the solution chosen was to use negative
permissions in a built in role called `WorkspaceCreationBan`.

# Rational

Using negative permissions is new territory, and not ideal. However,
workspaces are in a unique position.

Workspaces have 2 owners. The organization and the user. To prevent
users from creating a workspace in another organization, an [implied
negative
permission](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/policy.rego#L172-L192)
is used. So the truth table looks like: _how to read this table
[here](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/README.md#roles)_

| Role (example)  | Site | Org  | User | Result |
|-----------------|------|------|------|--------|
| non-org-member  | \_   | N    | YN\_ | N      |
| user            | \_   | \_   | Y    | Y      |
| WorkspaceBan    | \_   | N    | Y    | Y      |
| unauthenticated | \_   | \_   | \_   | N      |


This new role, `WorkspaceCreationBan` is the same truth table condition
as if the user was not a member of the organization (when doing a
workspace create/delete). So this behavior **is not entirely new**.

<details>

<summary>How to do it without a negative permission</summary>

The alternate approach would be to remove the implied permission, and
grant it via and organization role. However this would add new behavior
that an organizational role has the ability to grant a user permissions
on their own resources?

It does not make sense for an org role to prevent user from changing
their profile information for example. So the only option is to create a
new truth table column for resources that are owned by both an
organization and a user.

| Role (example)  | Site | Org  |User+Org| User | Result |
|-----------------|------|------|--------|------|--------|
| non-org-member  | \_   | N    |  \_    | \_   | N      |
| user            | \_   | \_   |  \_    | \_   | N      |
| WorkspaceAllow  | \_   | \_   |   Y    | \_   | Y      |
| unauthenticated | \_   | \_   |  \_    | \_   | N      |

Now a user has no opinion on if they can create a workspace, which feels
a little wrong. A user should have the authority over what is theres.

There is fundamental _philosophical_ question of "Who does a workspace
belong to?". The user has some set of autonomy, yet it is the
organization that controls it's existence. A head scratcher 🤔

</details>

## Will we need more negative built in roles?

There are few resources that have shared ownership. Only
`ResourceOrganizationMember` and `ResourceGroupMember`. Since negative
permissions is intended to revoke access to a shared resource, then
**no.** **This is the only one we need**.

Classic resources like `ResourceTemplate` are entirely controlled by the
Organization permissions. And resources entirely in the user control
(like user profile) are only controlled by `User` permissions.


![Uploading Screenshot 2025-02-26 at 22.26.52.png…]()

---------

Co-authored-by: Jaayden Halko <[email protected]>
Co-authored-by: ケイラ <[email protected]>
aslilac added a commit that referenced this issue Feb 27, 2025
Using negative permissions, this role prevents a user's ability to
create & delete a workspace within a given organization.

Workspaces are uniquely owned by an org and a user, so the org has to
supercede the user permission with a negative permission.

# Use case

Organizations must be able to restrict a member's ability to create a
workspace. This permission is implicitly granted (see
#16546 (comment)).

To revoke this permission, the solution chosen was to use negative
permissions in a built in role called `WorkspaceCreationBan`.

# Rational

Using negative permissions is new territory, and not ideal. However,
workspaces are in a unique position.

Workspaces have 2 owners. The organization and the user. To prevent
users from creating a workspace in another organization, an [implied
negative
permission](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/policy.rego#L172-L192)
is used. So the truth table looks like: _how to read this table
[here](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/README.md#roles)_

| Role (example)  | Site | Org  | User | Result |
|-----------------|------|------|------|--------|
| non-org-member  | \_   | N    | YN\_ | N      |
| user            | \_   | \_   | Y    | Y      |
| WorkspaceBan    | \_   | N    | Y    | Y      |
| unauthenticated | \_   | \_   | \_   | N      |


This new role, `WorkspaceCreationBan` is the same truth table condition
as if the user was not a member of the organization (when doing a
workspace create/delete). So this behavior **is not entirely new**.

<details>

<summary>How to do it without a negative permission</summary>

The alternate approach would be to remove the implied permission, and
grant it via and organization role. However this would add new behavior
that an organizational role has the ability to grant a user permissions
on their own resources?

It does not make sense for an org role to prevent user from changing
their profile information for example. So the only option is to create a
new truth table column for resources that are owned by both an
organization and a user.

| Role (example)  | Site | Org  |User+Org| User | Result |
|-----------------|------|------|--------|------|--------|
| non-org-member  | \_   | N    |  \_    | \_   | N      |
| user            | \_   | \_   |  \_    | \_   | N      |
| WorkspaceAllow  | \_   | \_   |   Y    | \_   | Y      |
| unauthenticated | \_   | \_   |  \_    | \_   | N      |

Now a user has no opinion on if they can create a workspace, which feels
a little wrong. A user should have the authority over what is theres.

There is fundamental _philosophical_ question of "Who does a workspace
belong to?". The user has some set of autonomy, yet it is the
organization that controls it's existence. A head scratcher 🤔

</details>

## Will we need more negative built in roles?

There are few resources that have shared ownership. Only
`ResourceOrganizationMember` and `ResourceGroupMember`. Since negative
permissions is intended to revoke access to a shared resource, then
**no.** **This is the only one we need**.

Classic resources like `ResourceTemplate` are entirely controlled by the
Organization permissions. And resources entirely in the user control
(like user profile) are only controlled by `User` permissions.


![Uploading Screenshot 2025-02-26 at 22.26.52.png…]()

---------

Co-authored-by: Jaayden Halko <[email protected]>
Co-authored-by: ケイラ <[email protected]>
gcp-cherry-pick-bot bot pushed a commit that referenced this issue Mar 3, 2025
Using negative permissions, this role prevents a user's ability to
create & delete a workspace within a given organization.

Workspaces are uniquely owned by an org and a user, so the org has to
supercede the user permission with a negative permission.

# Use case

Organizations must be able to restrict a member's ability to create a
workspace. This permission is implicitly granted (see
#16546 (comment)).

To revoke this permission, the solution chosen was to use negative
permissions in a built in role called `WorkspaceCreationBan`.

# Rational

Using negative permissions is new territory, and not ideal. However,
workspaces are in a unique position.

Workspaces have 2 owners. The organization and the user. To prevent
users from creating a workspace in another organization, an [implied
negative
permission](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/policy.rego#L172-L192)
is used. So the truth table looks like: _how to read this table
[here](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/README.md#roles)_

| Role (example)  | Site | Org  | User | Result |
|-----------------|------|------|------|--------|
| non-org-member  | \_   | N    | YN\_ | N      |
| user            | \_   | \_   | Y    | Y      |
| WorkspaceBan    | \_   | N    | Y    | Y      |
| unauthenticated | \_   | \_   | \_   | N      |


This new role, `WorkspaceCreationBan` is the same truth table condition
as if the user was not a member of the organization (when doing a
workspace create/delete). So this behavior **is not entirely new**.

<details>

<summary>How to do it without a negative permission</summary>

The alternate approach would be to remove the implied permission, and
grant it via and organization role. However this would add new behavior
that an organizational role has the ability to grant a user permissions
on their own resources?

It does not make sense for an org role to prevent user from changing
their profile information for example. So the only option is to create a
new truth table column for resources that are owned by both an
organization and a user.

| Role (example)  | Site | Org  |User+Org| User | Result |
|-----------------|------|------|--------|------|--------|
| non-org-member  | \_   | N    |  \_    | \_   | N      |
| user            | \_   | \_   |  \_    | \_   | N      |
| WorkspaceAllow  | \_   | \_   |   Y    | \_   | Y      |
| unauthenticated | \_   | \_   |  \_    | \_   | N      |

Now a user has no opinion on if they can create a workspace, which feels
a little wrong. A user should have the authority over what is theres.

There is fundamental _philosophical_ question of "Who does a workspace
belong to?". The user has some set of autonomy, yet it is the
organization that controls it's existence. A head scratcher 🤔

</details>

## Will we need more negative built in roles?

There are few resources that have shared ownership. Only
`ResourceOrganizationMember` and `ResourceGroupMember`. Since negative
permissions is intended to revoke access to a shared resource, then
**no.** **This is the only one we need**.

Classic resources like `ResourceTemplate` are entirely controlled by the
Organization permissions. And resources entirely in the user control
(like user profile) are only controlled by `User` permissions.


![Uploading Screenshot 2025-02-26 at 22.26.52.png…]()

---------

Co-authored-by: Jaayden Halko <[email protected]>
Co-authored-by: ケイラ <[email protected]>
stirby pushed a commit that referenced this issue Mar 4, 2025
…16786)

Cherry-picked feat: implement WorkspaceCreationBan org role (#16686)

Using negative permissions, this role prevents a user's ability to
create & delete a workspace within a given organization.

Workspaces are uniquely owned by an org and a user, so the org has to
supercede the user permission with a negative permission.

# Use case

Organizations must be able to restrict a member's ability to create a
workspace. This permission is implicitly granted (see
#16546 (comment)).

To revoke this permission, the solution chosen was to use negative
permissions in a built in role called `WorkspaceCreationBan`.

# Rational

Using negative permissions is new territory, and not ideal. However,
workspaces are in a unique position.

Workspaces have 2 owners. The organization and the user. To prevent
users from creating a workspace in another organization, an [implied
negative

permission](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/policy.rego#L172-L192)
is used. So the truth table looks like: _how to read this table

[here](https://github.com/coder/coder/blob/36d9f5ddb3d98029fee07d004709e1e51022e979/coderd/rbac/README.md#roles)_

| Role (example)  | Site | Org  | User | Result |
|-----------------|------|------|------|--------|
| non-org-member  | \_   | N    | YN\_ | N      |
| user            | \_   | \_   | Y    | Y      |
| WorkspaceBan    | \_   | N    | Y    | Y      |
| unauthenticated | \_   | \_   | \_   | N      |


This new role, `WorkspaceCreationBan` is the same truth table condition
as if the user was not a member of the organization (when doing a
workspace create/delete). So this behavior **is not entirely new**.

<details>

<summary>How to do it without a negative permission</summary>

The alternate approach would be to remove the implied permission, and
grant it via and organization role. However this would add new behavior
that an organizational role has the ability to grant a user permissions
on their own resources?

It does not make sense for an org role to prevent user from changing
their profile information for example. So the only option is to create a
new truth table column for resources that are owned by both an
organization and a user.

| Role (example)  | Site | Org  |User+Org| User | Result |
|-----------------|------|------|--------|------|--------|
| non-org-member  | \_   | N    |  \_    | \_   | N      |
| user            | \_   | \_   |  \_    | \_   | N      |
| WorkspaceAllow  | \_   | \_   |   Y    | \_   | Y      |
| unauthenticated | \_   | \_   |  \_    | \_   | N      |

Now a user has no opinion on if they can create a workspace, which feels
a little wrong. A user should have the authority over what is theres.

There is fundamental _philosophical_ question of "Who does a workspace
belong to?". The user has some set of autonomy, yet it is the
organization that controls it's existence. A head scratcher 🤔

</details>

## Will we need more negative built in roles?

There are few resources that have shared ownership. Only
`ResourceOrganizationMember` and `ResourceGroupMember`. Since negative
permissions is intended to revoke access to a shared resource, then
**no.** **This is the only one we need**.

Classic resources like `ResourceTemplate` are entirely controlled by the
Organization permissions. And resources entirely in the user control
(like user profile) are only controlled by `User` permissions.


![Uploading Screenshot 2025-02-26 at 22.26.52.png…]()

---------

Co-authored-by: Jaayden Halko <[email protected]>
Co-authored-by: ケイラ <[email protected]>

Co-authored-by: Steven Masley <[email protected]>
Co-authored-by: Jaayden Halko <[email protected]>
Co-authored-by: ケイラ <[email protected]>
@Kira-Pilot
Copy link
Member

@Emyrk was this resolved with the implementation of the WorkspaceCreationBan org role?

@jaaydenh we'll have to consider how we want to handle this negative role in our built-in roles table design.

@Emyrk
Copy link
Member

Emyrk commented Mar 12, 2025

@Emyrk was this resolved with the implementation of the WorkspaceCreationBan org role?

It should be resolved yes.

#16686

@Emyrk Emyrk closed this as completed Mar 12, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
multi-org temporary label for multiple organizations related work
Projects
None yet
Development

No branches or pull requests

5 participants