Skip to content

Push-based replication without excessive permissions #364

@anton-johansson

Description

@anton-johansson

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!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions