argoproj / argoproj/argo-cd

Inconsistent RBAC deny behavior when policies refer to overlapping SSO groups

Open
#17,547 1 comment 0 reactions 0 assignees View on GitHub
bug component:rbac version:EOL
Dominant language
Go
Stars
24.2k
Forks
7.8k
Avg merge
1d 14h
Merged PRs (30d)
246

Description

Checklist:

* [x] I've searched in the docs and FAQ for my answer: https://bit.ly/argocd-faq.
* [x] I've included steps to reproduce the bug.
* [x] I've pasted the output of `argocd version`.

**Describe the bug**

When a SSO user A is member of multiple SSO groups G1 and G2, if one RBAC policy grants a specific permission to group G1 and another policy denies it for group G2 (or user A directly), the end result for user A is allow.
This seems to be inconsistent with the expected behavior based on [ArgoCD's Casbin policy effect](https://github.com/argoproj/argo-cd/blob/master/assets/model.conf#L11) where deny always overrides allow.

**To Reproduce**

With Okta configured with SAML connector in Dex and the following in `argocd-rbac-cm`:
```
policy.csv: |
g, k8s-admins, role:admin
p, role:test, projects, get, *, deny
g, userA@example.com, role:test
policy.default: ""
policy.matchMode: glob
scopes: '[email,groups]'
```
where user `userA@example.com` is member of `k8s-admins` and `userA@example.com` groups as verified in the User Info page in ArgoCD UI.
User `userA@example.com` can still view the projects in the UI.

I'm not 100% sure but this seems to be possibly caused by a premature return when looping over groups [here](https://github.com/argoproj/argo-cd/blob/master/server/rbacpolicy/rbacpolicy.go#L151).
It should probably evaluate all groups first and then implement a policy effect consistent with the Casbin model on the aggregate result.

**Expected behavior**

User `userA@example.com` should be denied as soon as any policy denies access to any of the groups it is a member of.

**Version**

```shell
argocd: v2.9.6+ba62a0a
BuildDate: 2024-02-02T19:36:48Z
GitCommit: ba62a0a86d19f71a65ec2b510a39ea55497e1580
GitTreeState: clean
GoVersion: go1.21.6
Compiler: gc
Platform: linux/amd64
argocd-server: v2.10.0+2175939
BuildDate: 2024-02-06T14:28:43Z
GitCommit: 2175939ed6156ddd743e60f427f7f48118c971bf
GitTreeState: clean
GoVersion: go1.21.3
Compiler: gc
Platform: linux/amd64
Kustomize Version: v5.2.1 2023-10-19T20:13:51Z
Helm Version: v3.14.0+g3fc9f4b
Kubectl Version: v0.26.11
Jsonnet Version: v0.20.0
```

**Logs**

Casbin logs with `ARGOCD_RBAC_DEBUG=1` set:
```
2024/03/14 18:31:19 Request: dXNlckFAZXhhbXBsZS5jb20gb2t0YQ, projects, get, default ---> false
Hit Policy:
2024/03/14 18:31:19 Request: userA@example.com, projects, get, default ---> false
Hit Policy:
2024/03/14 18:31:19 Request: k8s-admins, projects, get, default ---> true
Hit Policy:
2024/03/14 18:31:19 Request: dXNlckFAZXhhbXBsZS5jb20gb2t0YQ, projects, get, infrastructure ---> false
Hit Policy:
2024/03/14 18:31:19 Request: userA@example.com, projects, get, infrastructure ---> false
Hit Policy:
2024/03/14 18:31:19 Request: k8s-admins, projects, get, infrastructure ---> true
Hit Policy:
```

Contributor guide

Open the contributing guide

Research direction

Start in server/rbacpolicy/rbacpolicy.go around the group loop near line 151, then compare its behavior with the Casbin policy effect in assets/model.conf. Reproduce with the provided argocd-rbac-cm policy.csv, overlapping SSO groups, and ARGOCD_RBAC_DEBUG=1. Done means a deny for any matching group or user overrides an allow consistently with the documented policy effect.

Written by the indexing model from the issue text.

Assessment

Tech stack
go, kubernetes
Domain
authorization, backend, security
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.