Skip to content

Commit

Permalink
Allow access to sealed secret services/proxy to any authenticated user
Browse files Browse the repository at this point in the history
This allows kubeseal to fetch the certificate public key (and perform other actions such as /verify and /rotate endpoints) even if the caller doesn't have otherwise the rights to access the kube-system namespace (or any other namespace where the sealed-secrets controller might have been deployed), as it often happens that users are not granted such broad permissions on production clusters.

We historically suggested users to just distribute the certificate out of bound and use the `--cert` flag.
However, with the advent of master key rotation, this is becoming increasingly more cumbersome, especially since
it's critical that users end up using the right certificate (i.e. the certificate has to be authenticated).
Master key rotation also requires users to periodically rotate the secrets, which requires access to the /rotate endpoint.

This change includes a fine-grained RBAC rule that allows access to the sealed-secrets controller HTTP API to any authenticated user in the cluster.
Users are still free to disable this feature by applying an override during deployment, but our default RBAC config should include it.

The controller currently exposes the following endpoints:

- `/healthz'
- `/v1/verify`
- `/v1/rotate`
- `/v1/cert.pem`

The controller already must not expose any secrets via the HTTP endpoint, since while RBAC would prevent
end-users to access the service via the proxy, nothing prevents any unprivileged workload in the cluster unless
admins have explicitly configured a strict network policy rule set.

Closes #166
  • Loading branch information
Marko Mikulicic committed Jul 31, 2019
1 parent 85b6e45 commit 516503c
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 0 deletions.
3 changes: 3 additions & 0 deletions cmd/controller/server.go
Expand Up @@ -26,6 +26,9 @@ type certProvider func() []*x509.Certificate
type secretChecker func([]byte) (bool, error)
type secretRotator func([]byte) ([]byte, error)

// httpserver starts an HTTP that exposes core functionality like serving the public key
// or secret rotation and validation. This endpoint is designed to be accessible by
// all users of a given cluster. It must not leak any secret material.
func httpserver(cp certProvider, sc secretChecker, sr secretRotator) {
httpRateLimiter := rateLimter()

Expand Down
27 changes: 27 additions & 0 deletions controller.jsonnet
Expand Up @@ -38,6 +38,26 @@ controller {
],
},

serviceProxierRole: kube.Role('sealed-secrets-service-proxier') + $.namespace {
rules: [
{
apiGroups: [
'',
],
resources: [
'services/proxy',
],
resourceNames: [
'http:sealed-secrets-controller:', // kubeseal uses net.JoinSchemeNamePort when crafting proxy subresource URLs
'sealed-secrets-controller', // but often services are referred by name only, let's not make it unnecessarily cryptic
],
verbs: [
'get',
],
},
],
},

unsealerBinding: kube.ClusterRoleBinding('sealed-secrets-controller') {
roleRef_: $.unsealerRole,
subjects_+: [$.account],
Expand All @@ -48,6 +68,13 @@ controller {
subjects_+: [$.account],
},

serviceProxierBinding: kube.RoleBinding('sealed-secrets-service-proxier') + $.namespace {
roleRef_: $.serviceProxierRole,
// kube.libsonnet assumes object here have a namespace, but system groups don't
// thus are not supposed to use the magic "_" here.
subjects+: [kube.Group('system:authenticated')],
},

controller+: {
spec+: {
template+: {
Expand Down

0 comments on commit 516503c

Please sign in to comment.