etcd-io / etcd-io/etcd-operator

Support enabling etcd authentication

Open
#302 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Go
Stars
164
Forks
72
Avg merge
22h 46m
Merged PRs (30d)
34

Description

Refer: https://etcd.io/docs/v3.6/op-guide/authentication/rbac/

### Summary

My long-term goal is to support operator managed `role` and `user` via `EtcdRole` and `EtcdUser`.

However, the current state of the project doesn't have supporting functionality yet, as auth isn't managed even for the root user. This issue is the first step in that direction.

The operator should support enabling etcd's built-in authentication system on managed clusters. This includes creating the root user/role, calling `auth enable`, and managing the root credentials in a Kubernetes Secret.

### Approaches

Option A: Auth field on EtcdCluster spec

We add directly to the existing spec. We have an `enabled` toggle for off/on, and a reference to a kubernetes secret that contains the admin credentials. If this already exists, the operator should use it. If not, the operator should create and use it.

```
apiVersion: operator.etcd.io/v1alpha1
kind: EtcdCluster
metadata:
name: my-cluster
spec:
size: 3
auth:
enabled: true
secretRef:
name: my-cluster-root-credentials
```

When `spec.auth.enabled=true`, the operator would follow the [Enabling authentication](https://etcd.io/docs/v3.6/op-guide/authentication/rbac/) steps... creating the root user, and enabling auth.


Option B: Separate EtcdAuth CRD

We introduce a standalone CRD that targets an existing cluster. Here there is no `enabled` boolean. If the resource exists, we enable auth. If not, we take no action.

```
apiVersion: operator.etcd.io/v1alpha1
kind: EtcdAuth
metadata:
name: my-cluster-auth
spec:
clusterRef:
name: my-cluster
secretRef:
name: my-cluster-root-credentials
```

A dedicated controller would handle the auth enable flow independently, with similar logic to above. This might be nice for separation of concerns, but has some ordering dependency as the cluster must be healthy before auth can be enabled, then the cluster controller needs to also read the EtcdAuth resource to get it's own credentials after auth has been enabled.

### Secret Ref

Both approaches use a Kubernetes Secret to store the root password.
If the user wants to pre-create the secret, they can, and the operator will just use the existing secret.
If the user doesn't care, then the operator will autogenerate a password and create the secret.
All subsequent calls will just use the secret content.

The username is always `root`.

### Notes

Existing functionality needs to take auth status into account.

When bootstrapping a cluster prior to auth being enabled, etcd client shouldn't be created with any auth info. Once auth is enabled, all clients must be created with the auth info.

From prior experience, the [AuthStatus](https://pkg.go.dev/go.etcd.io/etcd/client/v3#section-readme:~:text=//%20AuthStatus%20returns%20the%20status%20of%20auth%20of%20an%20etcd%20cluster.%0A%09AuthStatus(ctx%20context.Context)%20(*AuthStatusResponse%2C%20error)) call doesn't return a clean response. My current approach is
- try `AuthStatus()` with an unauthenticated client
- If succeeds, then the result is also false, auth is not enabled.
- If it fails with "user name is empty", then auth is likely enabled. Optionally (defensive) confirm by creating an authenticated client and calling `AuthStatus()` again.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.