- Rust 100%
| .cargo | ||
| kuyaseg-controller | ||
| .gitignore | ||
| Cargo.lock | ||
| Cargo.toml | ||
| deny.toml | ||
| LICENSE | ||
| Makefile.toml | ||
| opencode.jsonc | ||
| README.md | ||
| rust-toolchain.toml | ||
| rustfmt.toml | ||
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:
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:
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 (e.g. DB credentials in some cases), you should consider ESO 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:
# 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
seedvalue set for controller metadata.nameandmetadata.namespaceofDeterministicSecretresourcespec.keys.*.keyandspec.key.*.versionfor each generated key specified inDeterministicSecretresource
Thus, if seed secret remains stable and DeterministicSecret specification does not change - generated keys remain stable and predictable
To set the seed for the controller, deploy a v1/Secret and target the controller to it with KUYASEG_DETERMINISTIC_SEED env variable.
apiVersion: v1
kind: Secret
metadata:
name: controller-seed
namespace: testing
stringData:
my_seed: aabbcc123
KUYASEG_DETERMINISTIC_SEED=controller-seed/my_seed
When the later part /my_seed is omitted, controller will expect the seed key to contain seed value.
When the seed value changes, all known secrets are reconciled.
Feature comparison
We know there are plenty of decent, mature and well-adopted solutions like the one by mittwald and even ESO 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
|
Not supported | 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 and kindly e-mail us at reports@spushk.ru
Secret generation
To produce random secrets (RandomSecret, RandomSshSecret), operator uses aws-lc-rs+fips.
To produce deterministic secrets (DeterministicSecret, DeterministicSsh), operator uses Hc128 CSPRNG.
Secret persistence
Random secrets defined by RandomSecret and RandomSsh are unstable: deletion of generated Secret will produce new random value on next reconcilation.
Deterministic secrets defined by DeterministicSecret and DeterministicSsh are stable as long as the base seed and spec/version remain unchanged.
Deletion of generated Secret resources will lead to the same pseudo-random value put into the secret on next reconcilation.
Best effort is taken to ensure that secrets do not remain in memory longer then needed and/or after crush.