akuity / kargo

Application lifecycle orchestration
https://kargo.akuity.io/
Apache License 2.0
1.39k stars 114 forks source link

Proposal: as a dev, I can see globals credentials in my project #2132

Open Tchoupinax opened 3 weeks ago

Tchoupinax commented 3 weeks ago

Checklist

Proposed Feature

We are able to provide global credentials to Kargo be we don't know if they are working or not as the credentials tab only show credentials in the namespace of the project. We could also show global credentials, flagged as global in the front and not editable.

Motivation

It improves the user experience as

Suggested Implementation

I started looking at the code and we could edit the ListCredentials to add global credentials in the list of returned credentials. Also, we could flag global credentials with a property "global" to tell the UI to display them as it.

Discussion

The issue I met is the access to the secret. As far as I see, there is a rolebinding created for every Project so Kargo is able to read secrets from these namespace. With a first look, Kargo is not able to read global secrets from the global namespace (e.g. Kargo) but it should as it can read credentials for pulling artefacts. I'm not sure the way you would manage it so I would like to discuss the security implementation with you.

First option: Kargo already has the right to read secrets in the namespace (e.g. the namespace is kargo or argocd). => Nothing to do, we can list and add to the list Second option: Kargo has not the right to read secrets in the namespace and we don't want to give access to every namespace. So, clusterRoleBinding are added for every namespaces specified as global namespace.

What do you think?

Thanks you for your work!

krancour commented 3 weeks ago

Global credentials are most likely to be used when a Kargo admin wants all Projects to have access to certain repositories without needing to overtly share the credentials with Project users. (Let's ignore that this violates the principle of least privilege and assume that the Kargo admin understands the trade-off they are making when they do something like this.)

So if we assume Project users aren't meant to see those credentials, is it safe to further assume that you just want Project users to be aware that global credentials for certain repos exist? If that's the ask, that seems very reasonable to me.

In terms of implementation:

Although the API server heavily redacts credentials (Secrets) it returns, listing/getting them still requires the user to actually be granted access to them. (Because Kargo RBAC is pure k8s RBAC under the hood.) Granting access to the "global" creds is a thing I am not keen to do because anyone with those permissions will see unredacted credentials if/when using kubectl directly, for instance.

So the question is how do we allow users to be aware certain resources exist without giving them any permissions on them...

We can have the Kargo API server find global creds using its own ServiceAccount instead of assuming one that the user is federated with (which is what it normally does). This would remove the requirement for users to actually have access to those Secrets. Because it would behave so differently from the existing endpoints for listing/getting credentials, I would make completely separate endpoints for this.

In terms of UI, since these are system-level things and not Project-level things, I would probably want to present this as a new tab or something on the home page where, currently, we only show the listing of Projects, but I would let @rbreeze weigh in on that.

Tchoupinax commented 1 week ago

Hello @krancour,

First of all, thank you very much for your complete answer.

be aware that global credentials for certain repos exist?

Yeah, that's my point. As a user, I want to know that my repository has access to credentials but I do not care about getting/inspecting it. Moreover, it's a good way to check the apply of global credentials is well done and correctly understood by Kargo.

I understand the point of view of the security. As we only require to know the existence of secrets and how they are called, we can effectively use the service account of Kargo for that and only return a list of name/type.

Firstly I thought credentials would be listed like others credentials, with a label "global" that indicates precisely that the credential is a global one. We can list them otherside, but maybe it's not the easiest UX. I mean, when you are working on a project, having the whole list in one place is easiest. Also, if in the future scoped-global credentials exists, it will be easier too to know if the credential is available in this project.