feat: fine-grained capabilities and enterprise IAM schema extensions (#996)

Split coarse gateway capabilities into fine-grained variants to
support per-operation access control in the enterprise IAM regime.
Add additive schema fields for enterprise group and grant management.

Capability split (gateway registry):
- graph:read -> triples:read, sparql:read, graph-rag:read,
  graph-embeddings:read
- graph:write -> triples:write, graph-embeddings:write,
  entity-contexts:write
- documents:read -> documents:read, document-rag:read,
  document-embeddings:read, entity-contexts:read
- documents:write -> documents:write, document-embeddings:write
- rows:read -> rows:read, nlp-query:read, structured-query:read,
  row-embeddings:read

OSS role definitions expanded to include all new fine-grained
capability names — no behavioral change for OSS deployments.

Schema additions (IamRequest):
- group_id, member_type, member_id for group membership operations
- group (GroupInput), grant (GrantInput) for create/update payloads
- Decoder now handles capability, resource_json, parameters_json,
  authorise_checks (previously missing from translator)

Schema additions (IamResponse):
- group_json, groups_json, members_json, grants_json,
  effective_permissions_json for enterprise operation responses
- Encoder now emits authorise decision fields

Gateway registry:
- 16 enterprise IAM operations registered (create-group,
  add-group-member, add-user-grant, etc.) under iam:admin capability
This commit is contained in:
cybermaggedon 2026-06-22 20:23:34 +01:00 committed by GitHub
parent 8797d9d9ff
commit 09b8a1d347
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 147 additions and 18 deletions

View file

@ -506,18 +506,18 @@ _FLOW_SERVICES = {
"text-completion": "llm",
"prompt": "llm",
"mcp-tool": "mcp",
"graph-rag": "graph:read",
"document-rag": "documents:read",
"graph-rag": "graph-rag:read",
"document-rag": "document-rag:read",
"embeddings": "embeddings",
"graph-embeddings": "graph:read",
"document-embeddings": "documents:read",
"triples": "graph:read",
"graph-embeddings": "graph-embeddings:read",
"document-embeddings": "document-embeddings:read",
"triples": "triples:read",
"rows": "rows:read",
"nlp-query": "rows:read",
"structured-query": "rows:read",
"structured-diag": "rows:read",
"row-embeddings": "rows:read",
"sparql": "graph:read",
"nlp-query": "nlp-query:read",
"structured-query": "structured-query:read",
"structured-diag": "structured-query:read",
"row-embeddings": "row-embeddings:read",
"sparql": "sparql:read",
}
for _kind, _cap in _FLOW_SERVICES.items():
_register_flow_kind("flow-service", _kind, _cap)
@ -525,10 +525,10 @@ for _kind, _cap in _FLOW_SERVICES.items():
# Streaming import socket endpoints.
_FLOW_IMPORTS = {
"triples": "graph:write",
"graph-embeddings": "graph:write",
"document-embeddings": "documents:write",
"entity-contexts": "documents:write",
"triples": "triples:write",
"graph-embeddings": "graph-embeddings:write",
"document-embeddings": "document-embeddings:write",
"entity-contexts": "entity-contexts:write",
"rows": "rows:write",
}
for _kind, _cap in _FLOW_IMPORTS.items():
@ -537,10 +537,35 @@ for _kind, _cap in _FLOW_IMPORTS.items():
# Streaming export socket endpoints.
_FLOW_EXPORTS = {
"triples": "graph:read",
"graph-embeddings": "graph:read",
"document-embeddings": "documents:read",
"entity-contexts": "documents:read",
"triples": "triples:read",
"graph-embeddings": "graph-embeddings:read",
"document-embeddings": "document-embeddings:read",
"entity-contexts": "entity-contexts:read",
}
for _kind, _cap in _FLOW_EXPORTS.items():
_register_flow_kind("flow-export", _kind, _cap)
# ---------------------------------------------------------------------------
# Enterprise IAM operations.
#
# These are additive — they register alongside the OSS IAM operations.
# When the OSS regime receives an unknown operation it returns an error;
# when the enterprise regime is running, it handles them.
# ---------------------------------------------------------------------------
for _op in (
"create-group", "get-group", "list-groups",
"update-group", "delete-group",
"add-group-member", "remove-group-member", "list-group-members",
"add-group-grant", "remove-group-grant", "list-group-grants",
"add-user-grant", "remove-user-grant", "list-user-grants",
"resolve-effective-permissions",
):
register(Operation(
name=_op,
capability="iam:admin",
resource_level=ResourceLevel.SYSTEM,
extract_resource=_empty_resource,
extract_parameters=_no_parameters,
))

View file

@ -58,8 +58,18 @@ AUTHZ_CACHE_TTL_SECONDS = 60
_READER_CAPS = {
"agent",
"graph:read",
"triples:read",
"sparql:read",
"graph-rag:read",
"graph-embeddings:read",
"documents:read",
"document-rag:read",
"document-embeddings:read",
"entity-contexts:read",
"rows:read",
"nlp-query:read",
"structured-query:read",
"row-embeddings:read",
"llm",
"embeddings",
"mcp",
@ -73,6 +83,10 @@ _READER_CAPS = {
_WRITER_CAPS = _READER_CAPS | {
"graph:write",
"triples:write",
"graph-embeddings:write",
"document-embeddings:write",
"entity-contexts:write",
"documents:write",
"rows:write",
"collections:write",