Files
kms-operator/config/samples/crd/pushsecret/push-secret-with-template.yaml
zeekay b4e75f5f08 The API group is Hanzo's: kms.hanzo.ai/v1, and one version
The operator reconciled `secrets.lux.network` on Hanzo clusters. It is a
Lux-lineage component — it depends on luxfi/kms and luxfi/keys — but the group
is what every manifest in the estate names, and a Hanzo cluster naming a Lux
domain is the white-label rule broken in the most-copied place there is.

Group becomes kms.hanzo.ai, version stays v1 and there is no alpha: a second
served version is the thing a migration exists to remove, not something to
carry. The CRD bases are renamed to match, because the filename carries the
group and a stale name is a manifest that applies to nothing.

Two tests hold it. One pins group and version. The other walks the tree and
fails on any file still naming the old group — a rename that misses one
manifest ships a CRD the operator has no RBAC for, and that surfaces as "no
permission" long after the commit that caused it.

This is the operator half only. Nothing in a cluster moves until the objects
are migrated, and that sequence is not a sed: 147 live CRs, two of which are
creationPolicy Owner, so deleting those two CRs deletes the Secrets they
manage.
2026-08-20 17:10:49 -07:00

92 lines
4.4 KiB
YAML

apiVersion: kms.hanzo.ai/v1
kind: KMSPushSecret
metadata:
name: kms-api-secret-sample-push
spec:
resyncInterval: 1m
hostAPI: https://kms.hanzo.ai/api # This is the default hostAPI for the KMS API
# Optional, defaults to replacement.
updatePolicy: Replace # If set to replace, existing secrets inside KMS will be replaced by the value of the PushSecret on sync.
# Optional, defaults to no deletion.
deletionPolicy: Delete # If set to delete, the secret(s) inside KMS managed by the operator, will be deleted if the KMSPushSecret CRD is deleted.
destination:
projectId: <project-id>
environmentSlug: <env-slug>
secretsPath: <secret-path>
push:
secret:
secretName: push-secret-demo-with-templating
secretNamespace: default
template:
includeAllSecrets: false
data:
PKCS12_CERT_NO_PASSWORD: "{{ .PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert }}"
PKCS12_KEY_NO_PASSWORD: "{{ .PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key }}"
PKCS12_CERT_WITH_PASSWORD: '{{ .PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456" }}'
PKCS12_KEY_WITH_PASSWORD: '{{ .PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456" }}'
PEM_TO_PKCS12_PASS: '{{ pemToPkcs12Pass
(.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456")
(.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456")
"123456" }}'
PEM_TO_PKCS12_NO_PASSWORD: "{{ pemToPkcs12
(.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert)
(.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key)
}}"
FULL_PEM_TO_PKCS12_PASS: '{{ fullPemToPkcs12Pass
(.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12certPass "123456")
(.PKCS12_CONTENT_WITH_PASSWORD.Value | decodeBase64ToBytes | pkcs12keyPass "123456")
"123456" }}'
FULL_PEM_TO_PKCS12_NO_PASSWORD: "{{ fullPemToPkcs12
(.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert)
(.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12key)
}}"
FILTERED_PEM_CERT: '{{ filterPEM "CERTIFICATE" (printf "-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----" .JWK_PRIVATE_RSA_PKCS8.Value .PKCS12_CONTENT_NO_PASSWORD.Value) }}'
FILTERED_PEM_KEY: '{{ filterPEM "PRIVATE KEY" (printf "-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----\n-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----" .JWK_PRIVATE_RSA_PKCS8.Value .PKCS12_CONTENT_NO_PASSWORD.Value) }}'
# Will be empty with our current test data as there is no chain
CERT_CHAIN: '{{ filterCertChain "CERTIFICATE" (.PKCS12_CONTENT_NO_PASSWORD.Value | decodeBase64ToBytes | pkcs12cert) }}'
JWK_RSA_PUBLIC_PEM: "{{ jwkPublicKeyPem .JWK_PUB_RSA.Value }}"
JWK_ECDSA_PUBLIC_PEM: "{{ jwkPublicKeyPem .JWK_PUB_ECDSA.Value }}"
JWK_ECDSA_PRIVATE_PEM: "{{ jwkPrivateKeyPem .JWK_PRIV_ECDSA.Value }}"
JWK_RSA_PRIVATE_PEM: "{{ jwkPrivateKeyPem .JWK_PRIV_RSA.Value }}"
JSON_STR_TO_YAML: "{{ .TEST_JSON_DATA.Value | fromJsonStringToJson | toYaml }}"
FROM_YAML_TO_JSON: "{{ .TEST_YAML_STRING.Value | fromYaml | toJson }}"
YAML_ROUNDTRIP: "{{ .TEST_YAML_STRING.Value | fromYaml | toYaml }}"
TEST_LOWERCASE_STRING: "{{ .TEST_LOWERCASE_STRING.Value | upper }}"
# Only have one authentication method defined or you are likely to run into authentication issues.
# Remove all except one authentication method.
authentication:
awsIamAuth:
identityId: <machine-identity-id>
azureAuth:
identityId: <machine-identity-id>
gcpIamAuth:
identityId: <machine-identity-id>
serviceAccountKeyFilePath: </path-to-service-account-key-file.json>
gcpIdTokenAuth:
identityId: <machine-identity-id>
kubernetesAuth:
identityId: <machine-identity-id>
serviceAccountRef:
name: <secret-name>
namespace: <secret-namespace>
universalAuth:
credentialsRef:
secretName: <secret-name> # universal-auth-credentials
secretNamespace: <secret-namespace> # default