166 lines
7.8 KiB
Markdown
166 lines
7.8 KiB
Markdown
# K8s secret generator
|
|
|
|
> 🚧 Please, if you encountered this repo, note that this is under heavy construction.
|
|
|
|
> *AI*: This was also an exploration of opencode features, so there is some amount of AI-generated boilerplate.
|
|
|
|
## Features
|
|
|
|
### Generate namespaced secrets from specification
|
|
|
|
To generate arbitrary secret deploy `RandomSecret` resource:
|
|
|
|
```yaml
|
|
apiVersion: generator.kuyaseg.spushk.ru/v1alpha1
|
|
kind: RandomSecret
|
|
metadata:
|
|
name: secret
|
|
namespace: default
|
|
spec:
|
|
# Specify all keys to generate and put into secret
|
|
keys:
|
|
# Binary key - random byte sequence
|
|
- key: binary-key
|
|
# Change to regenerate value without altering spec
|
|
version: 0
|
|
# Determine secret shape
|
|
shape: !Bytes
|
|
# Set size of value in bytes
|
|
size: 64
|
|
# Password key - guaranteed UTF-8 character sequence with repeat period >= 3
|
|
- key: password-key
|
|
version: 0
|
|
shape: !Password
|
|
# Set length of password in symbols
|
|
length: 24
|
|
# Specify which symbols are allowed to use when generating password
|
|
dictionary: "abcdefghijklmnopqrstuvwxyz0123456789_"
|
|
# Required fields are `key` and `shape`
|
|
- key: default-binary-key
|
|
shape: !Bytes
|
|
- key: default-password
|
|
shape: !Password
|
|
# Adjust data, stringData and metadata of generated Secret
|
|
template: {}
|
|
```
|
|
|
|
#### SSH keys
|
|
|
|
To generate SSH key deploy `RandomSsh` resource:
|
|
|
|
```yaml
|
|
apiVersion: generator.kuyaseg.spushk.ru/v1alpha1
|
|
kind: RandomSsh
|
|
metadata:
|
|
name: ssh-secret
|
|
namespace: default
|
|
spec:
|
|
# Configure keypair configuration
|
|
keypair:
|
|
# If changes after last reconcilation, will force regeneration with new keypair
|
|
version: 0
|
|
# `ed25519` is default. `rsa` is WIP
|
|
algorithm: ed25519
|
|
# optional field to set pubkey comment
|
|
comment: mysecret
|
|
# Configure SSH private key
|
|
identity:
|
|
# The key to put generated identity to
|
|
key: private-key
|
|
# Adjust data, stringData and metadata of generated Secret
|
|
template: {}
|
|
# Configure SSH public key
|
|
pubkey:
|
|
# The key to put generated identity to
|
|
key: public-key
|
|
# Adjust data, stringData and metadata of generated Secret
|
|
template: {}
|
|
```
|
|
|
|
The following template properties have additional validation:
|
|
- `metadata.owner_references`: controller owner is not allowed
|
|
|
|
When reconciled, this resource will produce two `v1/Secret` resources in the same namespace:
|
|
- `<name>-identity`: private SSH key, which is stored in specified key
|
|
- `<name>-pubkey`: public SSH key which is stored in specified key
|
|
|
|
Both resources inherit namespace and name (as prefix) from `RandomSsh` resource and are immutable.
|
|
|
|
### Deterministic secrets
|
|
|
|
> ⚠️ This feature exists primarily for testing purposes, where security is less of a concern then repeatability.
|
|
>
|
|
> While there are use-cases for predictable secrets in production, you should consider [ESO](https://external-secrets.io)
|
|
> with secure external storage to share secrets between clusters and keep secrets stable.
|
|
>
|
|
> If the seed secret gets compromised - every past and future generated secret can be easliy computed.
|
|
|
|
Kuyaseg is able to provide deterministic source for secret and SSH keypair generation, offering idempotent sequence of secret values.
|
|
|
|
With deterministic secrets value remains the same even if specification was deleted and created anew.
|
|
|
|
This could be useful for testing, debugging and learning in local environments.
|
|
|
|
Deterministic secrets are created with `DeterministicSecret` and `DeterministicSsh` resources, matching `RandomSecret` and `RandomSsh` resource schema:
|
|
|
|
```yaml
|
|
# Schema matches the Secret from generator.kuyaseg.spushk.ru/v1alpha1
|
|
apiVersion: generator.kuyaseg.spushk.ru/v1alpha1
|
|
kind: DeterministicSecret
|
|
metadata:
|
|
name: deterministic-secret
|
|
namespace: testing
|
|
spec:
|
|
keys:
|
|
- key: debug-password
|
|
shape: !Password
|
|
template:
|
|
stringData:
|
|
username: debug-user
|
|
```
|
|
|
|
Secret values generated by deterministic generator depend on:
|
|
- Global `seed` value set for controller
|
|
- `metadata.name` and `metadata.namespace` of `DeterministicSecret` resource
|
|
- `spec.keys.*.key` and `spec.key.*.version` for each generated key specified in `DeterministicSecret` resource
|
|
|
|
Thus, if seed secret remains stable and DeterministicSecret specification does not change - generated keys remain stable and predictable
|
|
|
|
## Feature comparison
|
|
|
|
We know there are plenty of decent, mature and well-adopted solutions like the one by [mittwald](https://github.com/mittwald/kubernetes-secret-generator) and even [ESO](https://external-secrets.io) which can also generate secrets.
|
|
|
|
Here is a comparison.
|
|
|
|
||Kuyaseg|kubernetes-secret-generator|ESO||
|
|
|-|-|-|-|-|
|
|
|Generate cryptographically secure namespaced secrets|aws-lc-rs+fips, allows to specify generated **keys per resource**|Cryptographically secure, allows to specify generated **keys per resource**|Cryptographically secure, but generated keys are specified **per generator**||
|
|
|Generate SSH keypairs|Ed25519 and RSA OpenSSH keypairs, private and public keys **stored in separate secrets**|Both secret and public keys are **stored in one secret**|Not supported||
|
|
|Deterministic, reproducible secret generation|Available, Hc128 CSPRNG, optional, based on provided seed and secret specs. Stable|Not supported|Not supported||
|
|
|Target secret template|Respects <ul><li>annotations</li> <li>labels</li></ul>|[Not supported](https://github.com/mittwald/kubernetes-secret-generator/issues/88)|Allows to specity template in `ExternalSecret`||
|
|
|
|
## Security
|
|
|
|
⚠️ This software have never received independent security audit. I am not a security expert.
|
|
|
|
---
|
|
|
|
For security issues, please, view the [security policy](https://source.spushk.ru/security) and kindly e-mail
|
|
us at [reports@spushk.ru](mailto:reports@spushk.ru?subject=%5BSECURITY%5D%3A%20describe%20the%20issue&body=Thank%20you%20for%20submitting%20security%20report%20%E2%9D%A4%EF%B8%8F%0AWe%20kindly%20ask%20you%20not%20to%20publically%20disclose%20any%20information%20related%20to%20your%20findings%20just%20yet.%0APlease%2C%20fill%20out%20the%20following%20sections%20and%20provide%20any%20additional%20information%20you%27re%20willing%20to%20share.%0A%0A-------------------------------------------------------------------------------%20FINDING%0AWhat%20is%20the%20substance%20of%20an%20issue%3F%0A%0A-------------------------------------------------------------------------------%20AFFECTED%20SOFTWARE%0AWhich%20product%20and%20which%20versions%20is%20affected%3F%0A%0A-------------------------------------------------------------------------------%20REPRODUCTION%0APlease%2C%20share%20PoC%20if%20you%20have%20one%0A%0A-------------------------------------------------------------------------------%20DISCLOSURE%0AWhat%20are%20you%20expectations%20on%20disclosure%3F%0AWe%20kindly%20ask%20you%20not%20to%20share%20any%20information%20publically%0Aat%20least%20for%2090%20days%20since%20this%20report.%0A%0A-------------------------------------------------------------------------------%20CONTACT%0AHow%20do%20we%20contact%20you%3F)
|
|
|
|
---
|
|
|
|
### Secret generation
|
|
|
|
To produce random secrets (`RandomSecret`, `RandomSshSecret`), operator uses [aws-lc-rs+fips](https://docs.rs/aws-lc-rs/latest/aws_lc_rs/).
|
|
|
|
To produce deterministic secrets (`DeterministicSecret`, `DeterministicSsh`), operator uses [Hc128](https://docs.rs/rand_hc/latest/rand_hc/) CSPRNG.
|
|
|
|
### Secret persistence & memory
|
|
|
|
Random secrets defined by `RandomSecret` and `RandomSsh` are unstable. Deletion of generated `Secret` will lead to new random value on next reconcilation.
|
|
|
|
Deterministic secrets defined by `DeterministicSecret` and `DeterministicSsh` are stable as long as the base `seed` remains unchanged.
|
|
Deletion of generated `Secret` resources will lead to the same pseudo-random value put into the secret on next reconcilation as long as spec remains the same.
|
|
|
|
Best effort is taken to ensure that secrets do not remain in memory longer then needed and/or after crush.
|