Context
PR #15 stopped returning per-client posthogApiKey over the operator API (it was leaking every tenant's PostHog key to any unauthenticated caller via GET /api/clients). Important: nothing was deleted — the key is still stored in clients.posthog_api_key; PR #15 only stopped serializing it in HTTP responses. This issue is to decide where PostHog credentials should actually live so nothing is "lost" and multi-repo access is clean.
Two credential planes — keep them separate
1. Per-client PostHog key (runtime, multi-tenant)
- Home:
clients.posthog_api_key column (src/core/database/schema.ts). This is the correct place for per-tenant access to each client's PostHog project.
- Open bug (code audit finding M7): the modules currently ignore this column and query PostHog with the global
POSTHOG_PERSONAL_API_KEY instead — see src/modules/behavior-intelligence/index.ts:119 and src/modules/web-vitals/index.ts:194. They gate on the presence of client.posthogApiKey but then don't use it, so a client whose events live in a separate PostHog org silently returns empty.
- Decision needed: either wire the per-client key into
PostHogClient(...) / the RUM Authorization header, or formally deprecate the column if a single shared project is the intended model.
2. Shared / infrastructure credentials (CI + cross-repo)
Examples: the global POSTHOG_PERSONAL_API_KEY, NODE_AUTH_TOKEN (see companion issue). These should not live in per-repo .env. For full multi-repo access:
- Store as GitHub org-level secrets (Actions) so SEO-Bot, Website-Bot, and siblings all inherit them.
- At runtime, this repo already has an Infisical loader (
src/core/secrets.ts) and the org has a Quantum-L9/infisical-config repo — route shared secrets through Infisical rather than duplicating them per repo/.env.
Recommendation
| Credential |
Ideal home |
| Per-client PostHog key |
clients.posthog_api_key (DB) — and fix M7 so modules actually use it |
Shared POSTHOG_PERSONAL_API_KEY |
Org-level secret + Infisical |
NODE_AUTH_TOKEN (packages) |
Org-level secret + Infisical (see companion build issue) |
Document the resulting model in RUNBOOK.md § Environment Variable Reference.
Context
PR #15 stopped returning per-client
posthogApiKeyover the operator API (it was leaking every tenant's PostHog key to any unauthenticated caller viaGET /api/clients). Important: nothing was deleted — the key is still stored inclients.posthog_api_key; PR #15 only stopped serializing it in HTTP responses. This issue is to decide where PostHog credentials should actually live so nothing is "lost" and multi-repo access is clean.Two credential planes — keep them separate
1. Per-client PostHog key (runtime, multi-tenant)
clients.posthog_api_keycolumn (src/core/database/schema.ts). This is the correct place for per-tenant access to each client's PostHog project.POSTHOG_PERSONAL_API_KEYinstead — seesrc/modules/behavior-intelligence/index.ts:119andsrc/modules/web-vitals/index.ts:194. They gate on the presence ofclient.posthogApiKeybut then don't use it, so a client whose events live in a separate PostHog org silently returns empty.PostHogClient(...)/ the RUMAuthorizationheader, or formally deprecate the column if a single shared project is the intended model.2. Shared / infrastructure credentials (CI + cross-repo)
Examples: the global
POSTHOG_PERSONAL_API_KEY,NODE_AUTH_TOKEN(see companion issue). These should not live in per-repo.env. For full multi-repo access:src/core/secrets.ts) and the org has aQuantum-L9/infisical-configrepo — route shared secrets through Infisical rather than duplicating them per repo/.env.Recommendation
clients.posthog_api_key(DB) — and fix M7 so modules actually use itPOSTHOG_PERSONAL_API_KEYNODE_AUTH_TOKEN(packages)Document the resulting model in
RUNBOOK.md§ Environment Variable Reference.