Yet another k8s secret generator. This one respects any metadata, and will not mess up mariadb password
Find a file
2026-06-02 06:10:46 +05:00
.cargo chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00
kuyaseg-controller chore!: minor fixes here and there & move CRDs into submods & introduce serializer helpers 2026-06-02 06:10:46 +05:00
.gitignore fix: minor fixes, bring LLM for reviewing as a test 2026-05-16 18:36:41 +05:00
Cargo.lock chore!: minor fixes here and there & move CRDs into submods & introduce serializer helpers 2026-06-02 06:10:46 +05:00
Cargo.toml chore!: minor fixes here and there & move CRDs into submods & introduce serializer helpers 2026-06-02 06:10:46 +05:00
deny.toml chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00
LICENSE chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00
Makefile.toml chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00
opencode.jsonc fix: minor fixes, bring LLM for reviewing as a test 2026-05-16 18:36:41 +05:00
README.md chore!: minor fixes here and there & move CRDs into submods & introduce serializer helpers 2026-06-02 06:10:46 +05:00
rust-toolchain.toml chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00
rustfmt.toml chore(controller/reporting): init, setup prometheus basics, setup tracing event propagation 2026-05-15 05:38:07 +05:00

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 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

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
  • annotations
  • labels
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.