kube-yaseg/README.md
2026-05-16 18:42:27 +05:00

165 lines
8.1 KiB
Markdown

# K8s secret generator
> *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|Hc128 CSPRNG, 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, optional, based on provided secret data (e.g. SealedSecrets). Stable across clusters|Not supported|Not supported||
|Secret value stability|Created secrets are <ul><li>immutable</li> <li>created if accidentally deleted</li> <li>don't change unles you ask for it</li></ul>|Stable across reconcilations, but **changes on secret re-creation**|Only with real **external secret storage** (which ESO is designed for)||
|Target secret template|Respects almost full `Secret` (v1) spec, including <ul><li>annotations</li> <li>labels</li> <li>owner_references</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.