Skip to content
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

Let's introduce an RBAC HTTP REST API to manage RBAC-Config #16638

Closed
ggkhrmv opened this issue Dec 18, 2023 · 8 comments
Closed

Let's introduce an RBAC HTTP REST API to manage RBAC-Config #16638

ggkhrmv opened this issue Dec 18, 2023 · 8 comments
Labels
enhancement New feature or request

Comments

@ggkhrmv
Copy link

ggkhrmv commented Dec 18, 2023

Summary

The RBAC-Config currently can only be updated using the Kubernetes ConfigMap API.
This makes it very difficult to authorize permissions changes to the individual Casbin-based policies within the file.
Administrators usually receive permission to edit the entire argocd-rbac-cm object, where fine granular edits can not be distinguished by the Kubernetes ConfigMap API.
ArgoCD should provide interfaces for managing its RBAC settings, including write and read functionality.

Motivation

Considering other interfaces that Argo CD provides, an extension of the HTTP-based API (documented at /swagger-ui) for managing RBAC-related settings seems reasonable.
Especially when considering current operation patterns for managing access control: "editing in-line strig CSV via the k8s ConfigMap API" does come with a few limitations:

  • Developing automation is hard and would be based on a component outside of ArgoCD itself
  • Authorization pattern of current policies can not be extended to be fine granular (fine-grained access control on CSV content not possible)

Especially when using configuration automation tools such as Terraform, Ansible, Pulumi, cdk8s, and Crossplane the current Configmap Interface seems to be a blind spot.
Existing tools that rely on a real API can not be leveraged to administer the Casbin-based CSV for ArgoCD, often resulting in the necessity of manual operations.
Therefore the REST API will address the lack of structured configuration management and introduce interface stability.

An RBAC HTTP REST API would be great, as tools like https://github.com/crossplane-contrib/provider-argocd can directly interact with an API and abstract the persistent data (CSV).
Furthermore, this extension would provide a basis for delegated administration, so that management of a subset of permissions could be delegated to respective subjects.

Proposal

The following changes are proposed:

  • Extend the ArgoCD HTTP API with an endpoint to manage RBAC policies
  • Extend the current RBAC Implementation with write and delete functionality operating on the existing argocd-rbac-cm ConfigMap. This will be called by the HTTP request handlers accordingly.

As the Project API also defines roles, it will remain untouched. Only the global policies defined in the argocd-rbac-cm ConfigMap are subject to this change.

The REST API won't replace the ConfigMap solution and will be compatible with existing ConfigMaps, making it a non-breaking change.
Related issue: #16050

Pasted image 20231218140913

openapi: 3.1.0
info:
  title: ArgoCD RBAC Service - OpenAPI 3.1
  version: 1.0.11
paths:
  /api/v1/rbac/policies:
    get:
      tags:
        - RBACService
      summary: List returns a list of policies
      operationId: RBACService_ListPolicies
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RBACPolicyList'
  /api/v1/rbac/policies/{policyKey}:
    get:
      tags:
        - RBACService
      summary: Get returns a policy by name
      operationId: RBACService_GetPolicy
      parameters:
        - in: path
          name: policyKey
          schema:
            type: string
          description: Policy Key is the key of the policy to query
          required: true
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RBACPolicy'
    put:
      tags:
        - RBACService
      summary: Update updates a policy
      operationId: RBACService_AddPolicy
      parameters:
        - in: path
          name: policyKey
          schema:
            type: string
          description: Policy Key is the key of the policy to query
          required: true
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RBACPolicyRule'
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RBACPolicy'
    delete:
      tags:
        - RBACService
      summary: Delete deletes a policy
      operationId: RBACService_RemovePolicy
      parameters:
        - in: path
          name: policyKey
          schema:
            type: string
          description: Policy Key is the key of the policy to query
          required: true
      responses:
        '200':
          description: A successful response.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RBACPolicy'
components:
  schemas:
    RBACPolicy:
      description: RBACPolicy represents an RBAC (Role-Based Access Control) policy.
      type: object
      properties:
        policy:
          type: string
          example: |
              p, role:org-admin, applications, *, */*, allow
              p, role:org-admin, clusters, get, *, allow
              p, role:org-admin, repositories, get, *, allow
              p, role:org-admin, repositories, create, *, allow
              p, role:org-admin, repositories, update, *, allow
              p, role:org-admin, repositories, delete, *, allow
              p, role:org-admin, projects, get, *, allow
              p, role:org-admin, projects, create, *, allow
              p, role:org-admin, projects, update, *, allow
              p, role:org-admin, projects, delete, *, allow
              p, role:org-admin, logs, get, *, allow
              p, role:org-admin, exec, create, */*, allow

              g, your-github-org:your-team, role:org-admin
        policyKey:
          type: string
          examples : ["policy.csv", "policy.tenant.csv"]
    RBACPolicyList:
      description: RBACPolicyList is a list of RBACPolicy resources.
      type: object
      properties:
        items:
          type: array
          items:
            $ref: '#/components/schemas/RBACPolicy'
    RBACPolicyRule:
      description: >-
        RBACPolicyRule represents an RBAC (Role-Based Access Control) policy
        rule.
      type: object
      properties:
        policy:
          type: string
          example: |
              p, role:org-admin, applications, *, */*, allow
              p, role:org-admin, clusters, get, *, allow
              p, role:org-admin, repositories, get, *, allow
              p, role:org-admin, repositories, create, *, allow
              p, role:org-admin, repositories, update, *, allow
              p, role:org-admin, repositories, delete, *, allow
              p, role:org-admin, projects, get, *, allow
              p, role:org-admin, projects, create, *, allow
              p, role:org-admin, projects, update, *, allow
              p, role:org-admin, projects, delete, *, allow
              p, role:org-admin, logs, get, *, allow
              p, role:org-admin, exec, create, */*, allow

              g, your-github-org:your-team, role:org-admin
@ggkhrmv ggkhrmv added the enhancement New feature or request label Dec 18, 2023
@crenshaw-dev
Copy link
Member

I'm uneasy about introducing a feature which may encourage people to not use gitops to manage such an important config file.

@ggkhrmv
Copy link
Author

ggkhrmv commented Dec 18, 2023

I'm uneasy about introducing a feature which may encourage people to not use gitops to manage such an important config file.

The idea behind the API Service is to enable external operators, e.g. provider-argocd, to update and modify the RBAC Settings.

@gnunn1
Copy link

gnunn1 commented Jan 15, 2024

Some discussion on Slack as well here:

https://cloud-native.slack.com/archives/C01TSERG0KZ/p1705335678987749

@Joibel
Copy link
Member

Joibel commented Jan 16, 2024

I'm uneasy about introducing a feature which may encourage people to not use gitops to manage such an important config file.

The idea behind the API Service is to enable external operators, e.g. provider-argocd, to update and modify the RBAC Settings.

An external operator can also do this via the existing mechanism, so I also don't see the value.

@abacus3
Copy link

abacus3 commented Jan 16, 2024

I'm uneasy about introducing a feature which may encourage people to not use gitops to manage such an important config file.

This makes perfect sense. In the long-term users should exclusively be able to operate on a gitops fashioned workflow, which the current solution allows. Probably there are possible solutions that do meet the requirement of gitops and comes not with the inconveniences the current solution has (unstructured, not validated).
A slightly bit more context is available here: https://cloud-native.slack.com/archives/C01TSERG0KZ/p1705338616616669?thread_ts=1705335678.987749&cid=C01TSERG0KZ

I'm uneasy about introducing a feature which may encourage people to not use gitops to manage such an important config file.

The idea behind the API Service is to enable external operators, e.g. provider-argocd, to update and modify the RBAC Settings.

An external operator can also do this via the existing mechanism, so I also don't see the value.

Yet, the external operator would not really be able to perform structured changes with validation in place, which in the end basically results in just some better templating and rendering of the ConfigMap, essentially re-rendering the entire argocd-rbac-cm data.
There is no interface definition other than the k8s ConfigMap API which the external operator can rely on - it feels pretty hacky and unsafe to operate on another application's persistent data using the most generic API available, which is the k8s ConfigMap API. (this makes sense if you have some sort of immutable legacy application, where modifying the application's database tables manually is required, as the application does not implement a respective management interfaces)
In addition to that, we would not have the same IAM mechanisms as we have for the Argo CD CRs with k8s RBAC. (I can update Application CRs in k8s where k8s RBAC is enforce OR via Argo CD's REST API where Argo CD Casbin based RBAC is enforced)
Even supporting multiple ConfigMaps as discussed in #8324 would be an improvement towards enhancing IAM management features in Argo CD (based on the k8s RBAC API).

As mentioned in the slack discussion, I see a potential for more complex use-casaes, such as:

A k8s CRD based API (perhaps quite similar to the k8s RBAC API) would in addition tackle the potentially limiting size limit of k8s configmaps by spreading the individual RBAC snippets across many CRs. (this in fact would be breaking, as we would need to get rid of the argocd-rbac-cm entirely)

Ultimately, multi-tenant setups (except for project level permissions, as we have an API that is authorized by k8s RBAC) can not be performed by Argo CD standalone.
An external application will be needed to take care of extending Argo CD with the missing IAM management functionaltities.
Example: A user of a centrally managed Argo in shared usage and want to provider other users with custom access roles for projects I am the owner of (have full access).

@DingGGu
Copy link

DingGGu commented Jan 26, 2024

This may be a different story, but why doesn't ArgoCD use Kubernetes' RBAC and SelfSubjectAccessReview like Argo Workflow or other SSO tools?

It appears that authority control can be unified by declaring ArgoCd Object in advance in Kubernetes Role and RoleBinding and controlling it through Group in IdP.

@ggkhrmv
Copy link
Author

ggkhrmv commented Jan 26, 2024

This may be a different story, but why doesn't ArgoCD use Kubernetes' RBAC and SelfSubjectAccessReview like Argo Workflow or other SSO tools?

It appears that authority control can be unified by declaring ArgoCd Object in advance in Kubernetes Role and RoleBinding and controlling it through Group in IdP.

We're currently working on a design for a CRD-based API for RBAC config, similar to the k8s RBAC Service, since the REST API would discourage the use of GitOps for managing the config :)

@ggkhrmv
Copy link
Author

ggkhrmv commented May 2, 2024

New idea to introduce a CRD-based API for RBAC-Config (#18058), so closing this issue.

@ggkhrmv ggkhrmv closed this as not planned Won't fix, can't repro, duplicate, stale May 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment