feat: provision app secrets in notion-mcp-remote namespace (pre-sync) #7
Labels
No labels
domain:backend
domain:devops
domain:frontend
status:approved
status:in-progress
status:needs-fix
status:qa
type:bug
type:devops
type:feature
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
ldraney/notion-mcp-remote#7
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
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?
Type
Feature
Lineage
Standalone — scoped from
project-notion-mcp-remote. Followsservice-onboarding-sop→ "Application secrets" row of the Pre-Deploy Validation Checklist.Repo
forgejo_admin/notion-mcp-remoteUser Story
As an operator
I want the
notion-mcp-secretsKubernetes Secret pre-created in the target namespaceSo that ArgoCD's first sync produces a running pod instead of
CreateContainerConfigError.Context
Per SOP: kustomize overlays must not contain real secret data. The merged
k8s/deployment.yamlon main references the Kubernetes Secretnotion-mcp-secrets(notnotion-mcp-remote) viavalueFrom: secretKeyRefwith kebab-case keys. Real secret values must be materialised viakubectl create secret genericbefore the first ArgoCD sync (or beforetofu applyfor the initial bring-up if ArgoCD auto-syncs post-create).Secret shape is dictated by the existing manifest — do not invent new keys. The deployment spec maps each kebab-case secret key to an UPPER_SNAKE_CASE environment variable consumed by
server.py/auth/:base-urlBASE_URLserver.py— OAuth redirect + allowed-hostsoauth-client-idNOTION_OAUTH_CLIENT_IDauth/provider.py— Notion OAuthoauth-client-secretNOTION_OAUTH_CLIENT_SECRETauth/provider.py— Notion OAuthsession-secretSESSION_SECRETauth/storage.pyTokenStore— token encryptiononboard-secretONBOARD_SECRETDepends on
feat: register public Notion OAuth integration(provides client id/secret) and the namespace being created bytofu applyon pal-e-platform.File Targets
No repo file changes. This is a
kubectloperation executed against the live cluster. The target Secret is consumed byk8s/deployment.yaml(already on main) — this ticket does not modify that file.Acceptance Criteria
notion-mcp-remoteexistskubectl create secret generic notion-mcp-secrets -n notion-mcp-remotewith these kebab-case keys:base-url=https://notion-mcp-remote.tail5b443a.ts.netoauth-client-id(from registered Notion integration)oauth-client-secret(from registered Notion integration)session-secret(generated viaopenssl rand -hex 32)onboard-secret(generated viaopenssl rand -hex 32)kubectl get secret notion-mcp-secrets -n notion-mcp-remote -o jsonpath='{.data}' | jq 'keys'returns all 5 kebab-case keyskubectl rollout status deploy/notion-mcp-remote -n notion-mcp-remotereportssuccessfully rolled out(noCreateContainerConfigError, noCrashLoopBackOff)kubectl exec+env(or logs) confirmsBASE_URL,NOTION_OAUTH_CLIENT_ID,NOTION_OAUTH_CLIENT_SECRET,SESSION_SECRET,ONBOARD_SECRETare all set in the running containercurlagainst the pod's/healthendpoint returns 200 (proves the process booted past env-var loading)~/secrets/notion-mcp-remote/Test Expectations
Readystate once image lands (server.pyfails loudly on missing required env — green pod == secret shape is correct)kubectl logs -n notion-mcp-remote deploy/notion-mcp-remoteshows successful startup banner and noKeyError/missing envtracebackkubectl get secret notion-mcp-secrets -n notion-mcp-remote && kubectl rollout status deploy/notion-mcp-remote -n notion-mcp-remoteConstraints
notion-mcp-secretsand keys must be kebab-case — this matches the manifest already on main. Do not "normalise" to UPPER_SNAKE_CASE; thesecretKeyRef.keylookups are case-sensitive and would break the pod.kubectl applya YAML Secret manifest from a file that was ever in gitsession-secretandonboard-secretmust be generated at provision time (32+ bytes of entropy), not copy-pasted from anywhereChecklist
Related
project-notion-mcp-remotestory-notion-mcp-remote-ops-deploy-gitopsservice-onboarding-soparch-deployment-notion-mcp-remoteScope Review: NEEDS_REFINEMENT
Review note:
review-1047-2026-04-21Scope, traceability, and SOP alignment are solid. One concrete mismatch between the acceptance criteria and
k8s/deployment.yamlneeds reconciling before this moves totodo.[BODY]Secret name / key-shape mismatch. AC sayskubectl create secret generic notion-mcp-remotewith UPPER_SNAKE keys (NOTION_OAUTH_CLIENT_ID, etc.) referenced viaenvFrom.k8s/deployment.yamlactually references Secretnotion-mcp-secretswith kebab-case keys (oauth-client-id,oauth-client-secret,session-secret,onboard-secret,base-url) viavalueFrom: secretKeyRef. Running the AC as written will produceCreateContainerConfigError. Preferred fix (Option A, zero manifest churn): update AC to create secretnotion-mcp-secretswith the kebab-case keys listed above. Alternative (Option B): keep the UPPER_SNAKE /envFromshape and add a file target to patch the Deployment.[BODY](nit) Context paragraph saysenvFrom; current manifest usesvalueFrom. Pick one and make the ticket internally consistent.[LABEL]arch:k8s-secrethas no backingarch-k8s-secretnote. Considerarch:deployment-notion-mcp-remote(note exists, already documents the pre-sync secret decision) orarch:secrets-pipeline(platform-wide note). Optional.[BODY](nit) Add a future-rotation callout: rotatingSESSION_SECRETinvalidates encrypted tokens in the PVC; harmless on first bootstrap but worth documenting for the next operator.No decomposition needed (<5 min operator work once deps are met).
Refinement applied (consolidated spec) — review-1047-2026-04-21
Verdict from ticket review: NEEDS_REFINEMENT. The ticket body has been updated in place (per consolidated-spec convention — body is the single source of truth; this comment only logs the delta).
What changed and why
Root cause: The ticket specified Secret
notion-mcp-remotewith UPPER_SNAKE_CASE keys referenced viaenvFrom. The mergedk8s/deployment.yamlon main actually references Secretnotion-mcp-secretswith kebab-case keys viavalueFrom: secretKeyRef. Executing the ticket as written would produceCreateContainerConfigErrorbecausesecretKeyRef.keylookups are case-sensitive.Decision (per main-session router, reviewer Option A — zero churn): align the ticket to the existing manifest.
Delta
notion-mcp-remote→notion-mcp-secretsNOTION_OAUTH_CLIENT_ID/NOTION_OAUTH_CLIENT_SECRET/SESSION_SECRET/ONBOARD_SECRET/BASE_URL→oauth-client-id/oauth-client-secret/session-secret/onboard-secret/base-urlenvFrom→valueFrom: secretKeyRef(matches manifest)server.py/auth/provider.py/auth/storage.py(TokenStoretoken encryption) / onboarding endpointkubectl rollout statusgreen,/healthreturns 200, env vars resolved inside the container) — not just that the secret existsPreserved unchanged
tofu apply)kubectloperation, no repo file changes)arch-deployment-notion-mcp-remote(noarch-k8s-secretlink existed to remove)Verification
Manifest shape confirmed against
k8s/deployment.yamlat HEAD ofmain— all 5secretKeyRefentries target Secretnotion-mcp-secretswith the kebab-case keys listed above.Ready for re-review.
Scope Review: APPROVED
Review note:
review-1047-2026-04-21-v2(re-review after refinement)All gaps from the prior review (
review-1047-2026-04-21NEEDS_REFINEMENT) are closed. Verified againstk8s/deployment.yamlon main:notion-mcp-secretsmatches manifest lines 41/46/51/56/61base-url,oauth-client-id,oauth-client-secret,session-secret,onboard-secret) match manifest lines 42/47/52/57/62 exactlyvalueFrom: secretKeyRef(notenvFrom); Context language reconciledkubectl rollout status, in-containerenvverification of all 5 variables, and/health200 -- this exercises actualsecretKeyRefresolution end-to-endsecretKeyRef.keylookups)No action needed. Ready to advance from
backlogtotodo.