GKG Security Workstream
**Parent Epic**: [GitLab Knowledge Graph Second Iteration - GKG as a Service](https://gitlab.com/groups/gitlab-org/-/epics/19744)
## Problem to solve
The GitLab Knowledge Graph (GKG) aggregates sensitive data from across GitLab—issues, merge requests, pipelines, vulnerabilities, and code structure—into a single queryable service. This creates new security challenges we must address before GA.
**Design documents**:
- [Security Architecture](https://gitlab.com/gitlab-com/content-sites/handbook/-/blob/main/content/handbook/engineering/architecture/design-documents/gitlab_knowledge_graph/security.md)
- [Design Document MR](https://gitlab.com/gitlab-com/content-sites/handbook/-/merge_requests/16424)
### Security Concerns
1. **Centralized sensitive data**
- GKG becomes a high-value target since it holds data from multiple sources in one place
- A single vulnerability could expose confidential issues, security findings, and code intelligence
2. **Multi-tenant isolation on GitLab.com**
- Thousands of organizations share the same infrastructure
- We must guarantee that Organization A can never see Organization B's data, even through complex graph queries
3. **Complex permission model**
- GitLab permissions are hierarchical (groups → subgroups → projects) but also sparse (a user might have Reporter access to a group but be removed from one project)
- Confidential issues add another layer—users may access a project but not see certain issues
- The graph must respect all of these rules
4. **AI agents can now query the graph**
- LLMs construct queries via MCP tools, which means untrusted input flows through the system
- We need to ensure that even if an LLM is tricked, it cannot access unauthorized data
5. **New service boundaries**
- GKG introduces trust relationships between Rails, ClickHouse, NATS, Gitaly, and the graph service itself
- Each boundary is a potential attack surface
## Proposed solution
### For Data Access: Three authorization layers
Every query passes through three security checkpoints:
```
Layer 1: Organization isolation
└─ Every query includes organization_id filter from JWT
└─ Prevents cross-tenant access at the database level
Layer 2: Namespace-level access
└─ Traversal IDs from JWT limit which groups/projects are visible
└─ Prefix matching handles hierarchical permissions
Layer 3: Fine-grained redaction
└─ Rails checks Ability.allowed? for each result
└─ Handles confidential issues, sparse permissions, special cases
```
### Other Components: Security work streams
#### Authentication & service identity
- JWT tokens carry user identity and permissions from Rails to GKG
- MTLS ensures only authorized services can communicate
- **Questions to address**: How are JWTs signed? How do we rotate secrets? What happens if a certificate is compromised?
#### Authorization enforcement
- Layer 1 and 2 filters must be injected into every query path—no exceptions
- Aggregation queries (COUNT, SUM) are tricky because they can leak information even without returning raw data
- **Questions to address**: Can a user craft a query that bypasses filters? Do aggregations respect permissions?
#### Query engine hardening
- All user input goes through schema validation and allow-lists before becoming SQL
- No string concatenation—everything is parameterized
- Resource limits (depth caps, row limits, timeouts) prevent abuse
- **Questions to address**: Can malformed JSON slip through? Are all table/column names validated?
#### Data pipeline integrity
- Siphon CDC events flow through NATS to the indexer
- Events can arrive out of order; the system must handle this safely
- When a project moves between groups, permissions change—the graph must reflect this immediately
- **Questions to address**: Can someone inject fake CDC events? What happens during schema migrations?
#### Monitoring & incident response
- Track authorization filter usage and rejections
- Alert on anomalies (unusual query patterns, cross-tenant attempts)
- Audit log all queries with user context (if possible)
## References
**Discussion notes**:
- [GKG Discussion Log (Issue #268)](https://gitlab.com/gitlab-org/rust/knowledge-graph/-/issues/268)
- [Data Security Review Meeting](https://gitlab.com/gitlab-org/rust/knowledge-graph/-/issues/268#note_2909957706)
- [Authorization Discussion](https://gitlab.com/gitlab-org/rust/knowledge-graph/-/issues/268#note_2907961600)
- [Authz Review Meeting](https://gitlab.com/gitlab-org/rust/knowledge-graph/-/issues/268#note_2903882683)
**Threat models**:
- [GitLab Knowledge Graph Threat Model](gkg_threat_model.md)
- [Graph Query Engine Threat Model](gkg_query_engine_threat_model.md)
## Exit criteria
- [ ] Threat models reviewed and approved by AppSec
- [ ] Penetration testing completed with no critical findings
- [ ] JWT and MTLS implementations audited
- [ ] Authorization tested with realistic permission scenarios (sparse permissions, confidential issues)
- [ ] Aggregation authorization model documented and approved
- [ ] Security monitoring operational with alerts configured
- [ ] Incident response runbook created
epic