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:
@@ -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"] }
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -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"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user