fix(oidc): remove the API-server restart Jobs from GitOps

The oidc-bootstrap ArgoCD Application runs with selfHeal and prune. Three
Jobs in restart-apiserver.yaml kill the kube-apiserver process on each
control plane, and bootstrap.yaml carried a fourth Job that deletes the
mirror pods. ArgoCD recreated a deleted Job within two minutes, so the
kill repeated and every API server reached CrashLoopBackOff.

Remove all four. The OIDC authenticator already loaded, so the one-shot
restart is not needed again.
This commit is contained in:
2026-10-24 15:06:32 -07:00
parent 2f664c32d9
commit d1a7d3be6e
14 changed files with 560 additions and 167 deletions
@@ -0,0 +1,37 @@
{
"schema_version": 1,
"diagram_type": "architecture",
"meta": {
"title": "Poimen Memory — Schema Relations",
"quality_profile": "showcase",
"viewBox": [900, 480]
},
"components": [
{ "id": "node", "type": "database", "label": "memory_node", "sublabel": "Episodes (raw messages)", "pos": [40, 60], "size": [150, 55], "tag": "BIGSERIAL" },
{ "id": "entity", "type": "database", "label": "memory_entity", "sublabel": "Extracted entities", "pos": [260, 60], "size": [150, 55], "tag": "UUID" },
{ "id": "edge", "type": "database", "label": "memory_edge", "sublabel": "Facts / relationships", "pos": [480, 60], "size": [150, 55], "tag": "UUID" },
{ "id": "community", "type": "database", "label": "memory_community", "sublabel": "Entity clusters", "pos": [700, 60], "size": [150, 55], "tag": "UUID" },
{ "id": "pgvector", "type": "cloud", "label": "pgvector HNSW", "sublabel": "768-dim cosine search", "pos": [140, 260], "size": [160, 55], "tag": "nomic-embed-v2" },
{ "id": "tsvector", "type": "cloud", "label": "pg ts_rank", "sublabel": "Full-text search", "pos": [400, 260], "size": [160, 55], "tag": "GIN index" },
{ "id": "tenant", "type": "security", "label": "tenant_id", "sublabel": "Multi-tenant isolation", "pos": [660, 260], "size": [140, 55], "tag": "W7 / mig 014" }
],
"boundaries": [
{ "kind": "region", "label": "Temporal Knowledge Graph (Zep §2)", "wraps": ["node", "entity", "edge", "community"] },
{ "kind": "security-group", "label": "Search & Isolation", "wraps": ["pgvector", "tsvector", "tenant"] }
],
"connections": [
{ "id": "node-entity", "from": "node", "to": "entity", "variant": "emphasis" },
{ "id": "entity-edge", "from": "entity", "to": "edge", "variant": "emphasis" },
{ "id": "entity-community", "from": "community", "to": "entity", "variant": "dashed" },
{ "id": "edge-node", "from": "edge", "to": "node", "variant": "dashed" },
{ "id": "entity-vec", "from": "entity", "to": "pgvector", "variant": "default" },
{ "id": "entity-fts", "from": "entity", "to": "tsvector", "variant": "dashed" },
{ "id": "edge-fts", "from": "edge", "to": "tsvector", "variant": "dashed" },
{ "id": "tenant-all", "from": "tenant", "to": "entity", "variant": "security" }
],
"cards": [
{ "dot": "emerald", "title": "Three-Tier Graph", "items": ["memory_node → episode subgraph", "memory_entity → entity subgraph", "memory_edge → fact relationships", "memory_community → clusters (Phase 4)"] },
{ "dot": "rose", "title": "Bi-Temporal", "items": ["t_valid / t_invalid: event time", "t_created / t_expired: transaction time", "Contradiction: active → candidate → confirmed"] },
{ "dot": "cyan", "title": "Search", "items": ["HNSW: name, summary, fact embeddings", "ts_rank: BM25 fallback (always available)", "tenant_id: per-table isolation (mig 014)"] }
]
}
@@ -0,0 +1,158 @@
{
"schema_version": 1,
"diagram_type": "dataflow",
"meta": {
"title": "Poimen Memory \u2014 Schema Relations",
"viewBox": [
960,
480
],
"quality_profile": "showcase"
},
"stages": [
{
"label": "Episodes"
},
{
"label": "Entities"
},
{
"label": "Relationships"
},
{
"label": "Indexes"
}
],
"nodes": [
{
"id": "node",
"type": "database",
"label": "memory_node",
"sublabel": "Raw messages",
"stage": 0,
"row": 0,
"tag": "BIGSERIAL"
},
{
"id": "entity",
"type": "database",
"label": "memory_entity",
"sublabel": "Named entities",
"stage": 1,
"row": 0,
"tag": "UUID + tenant_id"
},
{
"id": "community",
"type": "database",
"label": "memory_community",
"sublabel": "Clusters (Phase 4)",
"stage": 1,
"row": 1,
"tag": "UUID"
},
{
"id": "edge",
"type": "database",
"label": "memory_edge",
"sublabel": "Facts + bi-temporal",
"stage": 2,
"row": 0,
"tag": "UUID + tenant_id"
},
{
"id": "hnsw",
"type": "cloud",
"label": "HNSW Index",
"sublabel": "768-dim cosine",
"stage": 3,
"row": 0,
"tag": "pgvector"
},
{
"id": "fts",
"type": "cloud",
"label": "GIN Index",
"sublabel": "ts_rank BM25",
"stage": 3,
"row": 1,
"tag": "full-text"
}
],
"flows": [
{
"from": "node",
"to": "entity",
"label": "LLM extraction",
"classification": "ingest",
"variant": "emphasis",
"route": "straight"
},
{
"from": "entity",
"to": "edge",
"label": "source + target FK",
"classification": "foreign key",
"variant": "emphasis",
"route": "straight"
},
{
"from": "entity",
"to": "community",
"label": "community_id",
"classification": "membership",
"variant": "dashed",
"route": "straight",
"labelDy": 30
},
{
"from": "edge",
"to": "hnsw",
"classification": "vector",
"variant": "default",
"route": "straight",
"label": "embedding",
"labelDy": -30
},
{
"from": "edge",
"to": "fts",
"label": "fact text",
"classification": "text",
"variant": "dashed",
"route": "vertical-channel",
"labelDy": 30
}
],
"cards": [
{
"dot": "emerald",
"title": "Three-Tier Graph",
"items": [
"memory_node \u2192 episodes (raw messages)",
"memory_entity \u2192 extracted entities",
"memory_edge \u2192 facts between entities",
"memory_community \u2192 clusters (Phase 4)"
]
},
{
"dot": "rose",
"title": "Bi-Temporal + Tenant",
"items": [
"t_valid/t_invalid: when true in reality",
"t_created/t_expired: system transaction time",
"tenant_id: row-level multi-tenant isolation",
"Contradiction: active \u2192 candidate \u2192 confirmed"
]
},
{
"dot": "cyan",
"title": "Search Indexes",
"items": [
"HNSW: name, summary, fact embeddings",
"GIN: ts_rank on name+summary and fact",
"RRF fusion: sem_weight + lex_weight"
]
}
]
}
@@ -0,0 +1,63 @@
{
"schema_version": 1,
"diagram_type": "sequence",
"meta": {
"title": "Service Acting on Behalf of User",
"viewBox": [1000, 600],
"column_fit": "spread",
"quality_profile": "showcase"
},
"participants": [
{ "id": "user", "type": "external", "label": "User", "sublabel": "browser" },
{ "id": "app", "type": "frontend", "label": "Web App", "sublabel": "poimen UI" },
{ "id": "authentik", "type": "security", "label": "Authentik", "sublabel": "OIDC" },
{ "id": "worker", "type": "backend", "label": "Backend Worker", "sublabel": "temporal/queue" },
{ "id": "memory", "type": "backend", "label": "Memory API", "sublabel": "poimen-memory" },
{ "id": "jwks", "type": "security", "label": "JWKS", "sublabel": "RS256" }
],
"segments": [
{ "from": 150, "to": 260, "label": "User Auth" },
{ "from": 270, "to": 370, "label": "Delegation" },
{ "from": 380, "to": 510, "label": "Downstream" }
],
"messages": [
{ "id": "login", "from": "user", "to": "app", "y": 165, "label": "login (OIDC)", "variant": "default" },
{ "id": "oidc-flow", "from": "app", "to": "authentik", "y": 200, "label": "authorization_code flow", "variant": "emphasis" },
{ "id": "user-jwt", "from": "authentik", "to": "app", "y": 235, "label": "user JWT {groups,roles}", "variant": "return" },
{ "id": "trigger-job", "from": "user", "to": "app", "y": 285, "label": "trigger async job", "variant": "default" },
{ "id": "queue-job", "from": "app", "to": "worker", "y": 320, "label": "enqueue job + user JWT", "variant": "emphasis", "note": "JWT passed as job metadata" },
{ "id": "job-ack", "from": "worker", "to": "app", "y": 355, "label": "job queued", "variant": "return" },
{ "id": "call-memory", "from": "worker", "to": "memory", "y": 400, "label": "POST /memory/ingest", "variant": "emphasis", "note": "Bearer <user JWT>" },
{ "id": "fetch-jwks", "from": "memory", "to": "jwks", "y": 435, "label": "GET /jwks", "variant": "dashed" },
{ "id": "jwks-keys", "from": "jwks", "to": "memory", "y": 470, "label": "RSA pubkey", "variant": "return" },
{ "id": "ingest-ok", "from": "memory", "to": "worker", "y": 505, "label": "202 Accepted", "variant": "return", "note": "uses USER's groups/roles" }
],
"activations": [
{ "participant": "user", "from": 160, "to": 291, "type": "external" },
{ "participant": "app", "from": 165, "to": 361, "type": "frontend" },
{ "participant": "authentik", "from": 195, "to": 241, "type": "security" },
{ "participant": "worker", "from": 315, "to": 511, "type": "backend" },
{ "participant": "memory", "from": 395, "to": 511, "type": "backend" },
{ "participant": "jwks", "from": 430, "to": 476, "type": "security" }
],
"cards": [
{
"dot": "emerald",
"title": "Delegation Pattern",
"items": [
"User JWT travels with the job payload",
"Worker uses user's token for downstream",
"Memory sees USER as the principal"
]
},
{
"dot": "rose",
"title": "Security Model",
"items": [
"No service-account escalation",
"User's permissions bound the action",
"Audit trail traces to user.sub"
]
}
]
}
@@ -0,0 +1,42 @@
{
"schema_version": 1,
"diagram_type": "architecture",
"meta": {
"title": "Memory Service Fine-Grained RBAC",
"quality_profile": "showcase",
"viewBox": [900, 520]
},
"components": [
{ "id": "jwt", "type": "security", "label": "JWT Token", "sublabel": "groups[] + roles[]", "pos": [40, 60], "size": [140, 60], "tag": "Authentik" },
{ "id": "cap-check", "type": "backend", "label": "Capability Check", "sublabel": "has_capability()", "pos": [260, 60], "size": [160, 60], "tag": "Phase 1" },
{ "id": "scope-checker", "type": "backend", "label": "Scope Checker", "sublabel": "filter_resources()", "pos": [500, 60], "size": [160, 60], "tag": "Phase 2" },
{ "id": "decision", "type": "backend", "label": "AccessDecision", "sublabel": "Allow / Deny", "pos": [740, 60], "size": [130, 60] },
{ "id": "project-scope", "type": "database", "label": "ProjectScope", "sublabel": "dev/staging/prod/*", "pos": [40, 200], "size": [140, 55] },
{ "id": "visibility-scope", "type": "database", "label": "VisibilityScope", "sublabel": "public/private", "pos": [220, 200], "size": [140, 55] },
{ "id": "owner-scope", "type": "database", "label": "OwnerScope", "sublabel": "self/any/user", "pos": [400, 200], "size": [140, 55] },
{ "id": "group-scope", "type": "database", "label": "GroupScope", "sublabel": "in_any_group()", "pos": [580, 200], "size": [140, 55] },
{ "id": "entities", "type": "database", "label": "Entities", "sublabel": "memory_entity", "pos": [40, 340], "size": [120, 50] },
{ "id": "edges", "type": "database", "label": "Edges", "sublabel": "memory_edge", "pos": [200, 340], "size": [120, 50] },
{ "id": "projects", "type": "database", "label": "Projects", "sublabel": "project_id", "pos": [360, 340], "size": [120, 50] },
{ "id": "convos", "type": "database", "label": "Conversations", "sublabel": "owner_id", "pos": [520, 340], "size": [120, 50] }
],
"boundaries": [
{ "kind": "security-group", "label": "Access Control Pipeline", "wraps": ["cap-check", "scope-checker", "decision"] },
{ "kind": "region", "label": "Scope Checkers", "wraps": ["project-scope", "visibility-scope", "owner-scope", "group-scope"] },
{ "kind": "region", "label": "Protected Resources", "wraps": ["entities", "edges", "projects", "convos"] }
],
"connections": [
{ "id": "jwt-to-cap", "from": "jwt", "to": "cap-check", "label": "claims", "variant": "emphasis" },
{ "id": "cap-to-scope", "from": "cap-check", "to": "scope-checker", "variant": "emphasis" },
{ "id": "scope-to-decision", "from": "scope-checker", "to": "decision", "variant": "emphasis" },
{ "id": "scope-to-proj", "from": "scope-checker", "to": "project-scope", "variant": "dashed", "fromSide": "bottom", "toSide": "top" },
{ "id": "scope-to-vis", "from": "scope-checker", "to": "visibility-scope", "variant": "dashed", "fromSide": "bottom", "toSide": "top" },
{ "id": "scope-to-owner", "from": "scope-checker", "to": "owner-scope", "variant": "dashed", "fromSide": "bottom", "toSide": "top" },
{ "id": "scope-to-group", "from": "scope-checker", "to": "group-scope", "variant": "dashed", "fromSide": "bottom", "toSide": "top" }
],
"cards": [
{ "dot": "emerald", "title": "Phase 1: Capability", "items": ["has_capability(memory:read)", "Checks roles[] claim", "Binary allow/deny"] },
{ "dot": "rose", "title": "Phase 2: Scope", "items": ["Project: dev/staging/prod", "Visibility: public/private", "Owner: self-owned only", "Group: poimen-admins/devs"] },
{ "dot": "cyan", "title": "JWT Claims", "items": ["groups: user.groups", "roles: attributes.roles", "permissions: group names"] }
]
}
+54
View File
@@ -0,0 +1,54 @@
{
"schema_version": 1,
"diagram_type": "sequence",
"meta": {
"title": "Service-to-Service (M2M) Authentication",
"viewBox": [1080, 520],
"column_fit": "spread",
"quality_profile": "showcase"
},
"participants": [
{ "id": "worker", "type": "backend", "label": "Ingest Worker", "sublabel": "temporal/cron" },
{ "id": "authentik", "type": "security", "label": "Authentik", "sublabel": "OIDC provider" },
{ "id": "memory", "type": "backend", "label": "Memory Service", "sublabel": "poimen-memory" },
{ "id": "jwks", "type": "security", "label": "JWKS", "sublabel": "RS256 keys" }
],
"segments": [
{ "from": 150, "to": 230, "label": "Token Mint" },
{ "from": 240, "to": 380, "label": "API + RBAC" }
],
"messages": [
{ "id": "token-req", "from": "worker", "to": "authentik", "y": 165, "label": "POST /token grant_type=password", "variant": "emphasis", "note": "client_id + username + app_password + scope" },
{ "id": "jwt-resp", "from": "authentik", "to": "worker", "y": 205, "label": "JWT {groups,roles,aud,iss}", "variant": "return", "note": "groups=[poimen-admins] roles=[memory:write]" },
{ "id": "api-call", "from": "worker", "to": "memory", "y": 260, "label": "POST /memory/ingest", "variant": "emphasis", "note": "Authorization: Bearer <JWT>" },
{ "id": "fetch-jwks", "from": "memory", "to": "jwks", "y": 295, "label": "GET /jwks (cached)", "variant": "dashed" },
{ "id": "jwks-resp", "from": "jwks", "to": "memory", "y": 330, "label": "RSA pubkey (kid)", "variant": "return" },
{ "id": "verify-ok", "from": "memory", "to": "worker", "y": 365, "label": "202 Accepted", "variant": "return", "note": "sig ✓ iss ✓ aud ✓ has_capability ✓" }
],
"activations": [
{ "participant": "worker", "from": 160, "to": 371, "type": "backend" },
{ "participant": "authentik", "from": 165, "to": 211, "type": "security" },
{ "participant": "memory", "from": 255, "to": 371, "type": "backend" },
{ "participant": "jwks", "from": 290, "to": 336, "type": "security" }
],
"cards": [
{
"dot": "emerald",
"title": "M2M Pattern",
"items": [
"grant_type=password (Authentik aliases client_credentials)",
"App-password token authenticates the service account",
"NOT client_secret — that creates nameless SA"
]
},
{
"dot": "rose",
"title": "JWT Claims",
"items": [
"groups: from user.groups (poimen-admins)",
"roles: from user.attributes.roles",
"iss/aud: per-provider issuer"
]
}
]
}
+61
View File
@@ -0,0 +1,61 @@
{
"schema_version": 1,
"diagram_type": "sequence",
"meta": {
"title": "User Direct Access with JWT",
"viewBox": [1000, 640],
"column_fit": "spread",
"quality_profile": "showcase"
},
"participants": [
{ "id": "user", "type": "external", "label": "User", "sublabel": "browser" },
{ "id": "app", "type": "frontend", "label": "Web App", "sublabel": "poimen UI" },
{ "id": "authentik", "type": "security", "label": "Authentik", "sublabel": "OIDC provider" },
{ "id": "memory", "type": "backend", "label": "Memory API", "sublabel": "poimen-memory" },
{ "id": "jwks", "type": "security", "label": "JWKS", "sublabel": "RS256 keys" }
],
"segments": [
{ "from": 150, "to": 370, "label": "OIDC Login" },
{ "from": 380, "to": 540, "label": "API + RBAC" }
],
"messages": [
{ "id": "click-login", "from": "user", "to": "app", "y": 165, "label": "click Login", "variant": "default" },
{ "id": "redirect-auth", "from": "app", "to": "authentik", "y": 200, "label": "redirect /authorize", "variant": "emphasis", "note": "scope=openid groups roles" },
{ "id": "show-login", "from": "authentik", "to": "user", "y": 235, "label": "login form", "variant": "default" },
{ "id": "submit-creds", "from": "user", "to": "authentik", "y": 270, "label": "username + password", "variant": "security" },
{ "id": "auth-code", "from": "authentik", "to": "app", "y": 305, "label": "redirect ?code=xxx", "variant": "return" },
{ "id": "exchange-token", "from": "app", "to": "authentik", "y": 340, "label": "POST /token code=xxx", "variant": "emphasis" },
{ "id": "jwt-resp", "from": "authentik", "to": "app", "y": 375, "label": "JWT {groups,roles,sub}", "variant": "return" },
{ "id": "query-api", "from": "app", "to": "memory", "y": 420, "label": "GET /memory/query", "variant": "emphasis", "note": "Authorization: Bearer <JWT>" },
{ "id": "fetch-jwks", "from": "memory", "to": "jwks", "y": 455, "label": "GET /jwks (cached)", "variant": "dashed" },
{ "id": "jwks-keys", "from": "jwks", "to": "memory", "y": 490, "label": "RSA pubkey", "variant": "return" },
{ "id": "query-resp", "from": "memory", "to": "app", "y": 525, "label": "200 JSON results", "variant": "return", "note": "has_capability(memory:read) ✓" }
],
"activations": [
{ "participant": "user", "from": 160, "to": 276, "type": "external" },
{ "participant": "app", "from": 165, "to": 531, "type": "frontend" },
{ "participant": "authentik", "from": 195, "to": 381, "type": "security" },
{ "participant": "memory", "from": 415, "to": 531, "type": "backend" },
{ "participant": "jwks", "from": 450, "to": 496, "type": "security" }
],
"cards": [
{
"dot": "emerald",
"title": "Authorization Code Flow",
"items": [
"User authenticates directly with Authentik",
"App exchanges code for JWT",
"Scopes: openid groups roles permissions"
]
},
{
"dot": "rose",
"title": "JWT Contents",
"items": [
"iss: .../application/o/poimen/",
"aud: poimen (provider client_id)",
"groups: user's group memberships"
]
}
]
}