fix(hermes): give the store of generated secrets an account of its own namespace #397
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/hermes-store-kubernetes"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
What was wrong
Both
secretsKustomizations failed at admission and never became ready, soenvandhermeswaited on them — the ExternalSecrets of the mounted.envwere never created and the new specification of the pod was never applied (that is why the pods did not roll). The operator's webhook named the rule:The store of the previous change named an account in
security— the namespace of the operator — while a namespaced store may authenticate only as an account of its own namespace, and by design never as the operator's mounted one.What this fixes
kubernetes/apps/{grachevaeu,grachevko}/hermes/secrets/app/secretstore-kubernetes.yaml— the account the store authenticates as moves into the namespace of the store: aServiceAccountof the instance, aRolewith the two permissions the operator documents for a store (read the secrets of that namespace — neitherlistnorwatchcan be narrowed byresourceNames— and review its own rules throughSelfSubjectRulesReview) and aRoleBindingthat binds them. TheSecretStoreitself keeps the provider, the pinnedremoteNamespaceand the CA of the API server; it now reads exactly the namespace it belongs to.hermes-api-keythrough the store namedkubernetes, and the mount, the Secret name and the generator stay as they are.Verified
flate test all -p ./kubernetes/flux/cluster— 308 passed.flate build ks secrets -p ./kubernetes/flux/cluster -n grachevaeuand-n grachevkorenderServiceAccount,Role,RoleBinding,SecretStoreand bothExternalSecrets of the instance.After the merge
kv/grachevaeu/hermesmust hold the keys under the variable names —DEEPSEEK_API_KEY,TELEGRAM_BOT_TOKEN, ... It still holdsdeepseek_keyandtelegram_bot_token; once the store works, the ExternalSecret of that instance stays inSecretSyncedErroruntil the record is rewritten (the sync repeats every minute, so the fix needs no nudge):flux reconcile kustomization secrets -n grachevaeu(thenenv, thenhermes, and the same forgrachevko); or wait for the interval.hermes-keysingrachevaeu(nothing creates it any more).Rollback
git revertof the merge commit: the previous store shape is rejected at admission, so a rollback returns to the state wheresecrets/envdo not reconcile and the pods keep their old specification — the running pods are unaffected either way.Failed to update PR description
PR Reviewer Guide 🔍
Here are some key observations to aid the review process:
PR Code Suggestions ✨
Explore these optional code suggestions:
Move selfsubjectrulesreviews to a ClusterRole
selfsubjectrulesreviewsis a cluster-scoped authorization.k8s.io resource, so itcannot be granted by a namespaced
Role. Keep the namespace-scoped secret access inthe
Role, and move the self-subject rules review permission to aClusterRoleboundto the ServiceAccount with a
ClusterRoleBindingthat also covers the grachevkoinstance.
kubernetes/apps/grachevaeu/hermes/secrets/app/secretstore-kubernetes.yaml [19-29]
Suggestion importance[1-10]: 9
__
Why: This fixes a critical RBAC validity issue:
selfsubjectrulesreviewsis cluster-scoped and cannot be granted by a namespacedRole. The proposedClusterRoleandClusterRoleBindingcorrectly restore the needed permission across both namespaces.Remove invalid namespaced role rule
Remove the cluster-scoped
selfsubjectrulesreviewsrule from this namespacedRole; itbelongs in a
ClusterRole. The first file'sClusterRoleBindingalready binds thisnamespace's
secrets-readerServiceAccount to the sharedsecrets-reader-selfsubjectrulesreviewClusterRole.kubernetes/apps/grachevko/hermes/secrets/app/secretstore-kubernetes.yaml [10-20]
Suggestion importance[1-10]: 6
__
Why: The removal is correct because
selfsubjectrulesreviewscannot be placed in a namespacedRole, but this change relies on aClusterRoleBindingthat is not present in the current diff. Applied alone, it would drop the required permission.