AI API key not managed
warningai-api-key-unmanaged
This AI vendor is reached with an API key, and nothing in the design holds or rotates that key. It ends up in environment files or code, every caller shares it, and a single leak runs up the vendor bill until someone notices. Put the key in a key-management component, or say it is held there with keyStore.
- Severity
- warning
- Selects
- every node of kind ai-service
- Components in scope
- 126
It looks at every node of kind ai-service, and fires when:
- — all of these hold:
- — the node's `auth` is "api-key"
- — the node's `keyStore` is false
- — the node has at least one incoming edge from an app-server, worker or client
- — this does not hold:
- — the design contains a node of kind key-management
AI service '{{node.id}}' is called with an API key, the key is not held in a key-management component, and the design has none.Reference designs whose broken twin names this rule in its header. The gate reads the same header, and fails when a rule no design trips.
# yaml-language-server: $schema=../schema/rule.schema.json # An AI vendor reached with an API key, called from the team's own servers, workers or clients, # with the key not declared as held in a key-management component and no key-management node in # the design. The key then lives in configuration or code, unrotated, and one leak bills the account. # Tripped by: designs/reference/llm-gateway/design.broken.yaml and designs/reference/linear-sync/design.broken.yaml schemaVersion: "1" type: "rule" id: "ai-api-key-unmanaged" severity: "warning" select: node: kind: "ai-service" when: all: - prop: "auth" equals: "api-key" - prop: "keyStore" equals: false - hasEdge: direction: "in" peerKind: ["app-server", "worker", "client"] - not: hasNode: kind: "key-management" message: "AI service '{{node.id}}' is called with an API key, the key is not held in a key-management component, and the design has none."