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

Push-based replication without excessive permissions #364

Open
anton-johansson opened this issue Jan 27, 2025 · 1 comment
Open

Push-based replication without excessive permissions #364

anton-johansson opened this issue Jan 27, 2025 · 1 comment

Comments

@anton-johansson
Copy link

Hey all! I just found this repository, which seems to fit my need perfectly. I have an API that consists of multiple micro-services, but they all share the same domain. They are deployed in individual namespaces, and I need to replicate a Secret created by cert-manager to all those namespaces.

Push-based replication via label selector seems to be a perfect fit. I can simply label those namespaces.

However, looking at the Kubernetes manifests generated by the Helm chart, the permissions feels very excessive. The service account will have full permissions to read and write secrets in any namespace. This feels like a security risk.

Wouldn't it be possible to limit the service account so that it can only create and update secrets? Why would the push-based setup require read access?

Wouldn't it also be possible to limit the service account so it can only access secrets with a specific name?

Here is an example:
deploy/helm-chart/kubernetes-replicator/templates/rbac.yaml (but with focus on secret and some variables replaced):

---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: {{ include "kubernetes-replicator.fullname" . }}
  labels:
    {{- include "kubernetes-replicator.labels" . | nindent 4 }}
rules:
  - apiGroups:
    - ""
    resources:
    - namespaces
    verbs:
    - get
    - watch
    - list
  - apiGroups:
    - ""
    resources:
    - secrets
    verbs:
    - create
    - update
    - patch
    - delete
    resourceNames:
    - my-api-secret

Of course, the service account still needs to be able to read and watch those secrets that are being replicated. But I guess that could be done separately, with Role and RoleBinding (in addition to the existing ClusterRole and ClusterRoleBinding), specifically in the namespace where the secrets (certificates) are. Something like this:

These are defined outside kubernetes-replicator, in the namespace that hosts my certificates/secrets:

---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secrets-replicator
  namespace: api-certificates
rules:
  - apiGroups:
    - ""
    resources:
    - secrets
    verbs:
    - get
    - watch
    - list

---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: secrets-replicator
  namespace: api-certificates
roleRef:
  kind: Role
  name: secrets-replicator
  apiGroup: rbac.authorization.k8s.io
subjects:
  - kind: ServiceAccount
    name: <name of the service account for kubernetes-replicator>
    namespace:<namespace of kubernetes-replicator>

What do you think? Maybe I'm overthinking the whole thing? Would it even work? I guess there is nothing that stops me from setting this up myself, and simply just configuring kubernetes-replicator with that service account, via the Helm value serviceAccount.name. But maybe it would be a good thing to document it?

Any thoughts are appreciated!

@anton-johansson
Copy link
Author

Okay, so I tried setting this up myself, and it almost worked all the way. The problem lies here:

https://github.com/mittwald/kubernetes-replicator/blob/master/replicate/secret/secrets.go#L38-L43

I would love it if kubernetes-replicator had support for specifying in which namespace it should watch for secrets in. In my case, I only need a single namespace, so that would be quite simple. I believe we could simply replace the "" empty string parameters to .Secrets("") to something that we configure as an argument to the application.

Here are my Helm values right now:

image:
  pullPolicy: IfNotPresent
serviceAccount:
  create: false
  name: certificate-replicator
replicationEnabled:
  secrets: true
  configMaps: false
  roles: false
  roleBindings: false
  serviceAccounts: false

The service account has been created separately, according to what I suggested in my previous post.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant