Object storage (linode): source accessKeyId from obj-secrets like secretAccessKey, so key rotation needs no git write
Nobody has claimed this yet.
- Dominant language
- Go Template
- Stars
- 2.3k
- Forks
- 186
- Avg merge
- 3d 11h
- Merged PRs (30d)
- 66
Description
### Summary
The `linode` object-storage provider sources the two halves of the S3 credential asymmetrically: `secretAccessKey` is read from the `obj-secrets` Secret (great — an operator can populate it via ESO and rotate freely), but `accessKeyId` is **inlined from git settings**. Because Linode OBJ keys rotate as a *pair*, this forces any operator that rotates keys to write the new `accessKeyId` back into the values git repo on every rotation — carrying a non-secret identifier through git solely because its paired secret is handled cleanly.
Request: let `accessKeyId` also be sourced from `obj-secrets` (or a native Secret), symmetric with `secretAccessKey`.
### Current behavior (apl-core v6.0.0)
From the templating:
`values/loki/loki-raw.gotmpl`
```gotmpl
AWS_ACCESS_KEY_ID: {{ $obj.linode.accessKeyId }} # inlined from env/settings/obj.yaml (git)
AWS_SECRET_ACCESS_KEY: '{{ "{{ .secretAccessKey | toString }}" }}'
- secretKey: secretAccessKey
remoteRef:
key: obj-secrets # from the obj-secrets Secret (ESO-friendly)
property: provider_linode_secretAccessKey
```
`values/harbor/harbor-raw.gotmpl` does the same (`S3_STORAGE_ACCOUNT` / `REGISTRY_STORAGE_S3_ACCESSKEY` ← `{{ $obj.linode.accessKeyId }}`; secret ← `obj-secrets.provider_linode_secretAccessKey`).
And `env/settings/obj.yaml` (`AplObjectStorage`) carries `spec.provider.linode.accessKeyId` as a plain setting (schema `additionalProperties: false`, so the secret half is deliberately kept out).
### Why it's a problem
A managed-App-Platform operator that provisions **and rotates** the OBJ access keys out-of-band (our case: Linode Landing Zone) can deliver `secretAccessKey` into `obj-secrets` via ESO/OpenBao and rotate with **zero git writes** — exactly right. But because `accessKeyId` is git-inlined and a rotation mints a *new pair*, the operator must also push the new `accessKeyId` into the values repo each rotation to keep it paired. That forces a git-sync reconciler holding a `Contents: write` token — a lot of moving parts to carry a **non-secret identifier that changes on the same cadence as the secret already handled cleanly**.
### Proposed options
1. **Extend the `obj-secrets` contract**: add a `provider_linode_accessKeyId` property and template `AWS_ACCESS_KEY_ID` from it (mirroring `secretAccessKey`). Operators populate one Secret with both keys via ESO; no git writes on rotation.
2. **Optional secret ref**: add `spec.provider.linode.accessKeyIdSecretRef` (nativeSecrets-style). When set, source `accessKeyId` from the referenced Secret; otherwise fall back to the inline settings value (fully backward compatible).
Either makes the two halves of the credential rotate together through one ESO-managed Secret, and lets external operators drop the git-write token + reconciler they otherwise need only for the access-key id.
### Environment
- apl-core `v6.0.0` (managed App Platform / apl-operator `1.16.0`)
- Provider: `linode`; consumers observed: Loki, Harbor (same pattern in gitea/keycloak/kubeflow-pipelines `-raw.gotmpl`)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with values/loki/loki-raw.gotmpl, values/harbor/harbor-raw.gotmpl, and env/settings/obj.yaml; compare the existing secretAccessKey path with the inline accessKeyId path, then inspect the other named -raw.gotmpl consumers. Done means the two Linode credential fields can rotate through the supported Secret path without requiring a git write, while preserving the stated compatibility behavior if the fallback option is selected.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- kubernetes
- Domain
- cloud, infrastructure
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 58/100