1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
|
# GitLab Cedar Authorization Design (Simplified)
This document describes the simplified design for implementing GitLab-style authorization using Cedar policies in the `authzd` service, without feature or license checks.
## Overview
The `authzd` service implements a Policy Decision Point (PDP) that authorizes GitLab REST API operations using Cedar policies based purely on user access levels and project visibility.
## Architecture
### Entity Model
The Cedar entity model mirrors GitLab's core entities:
- **User**: GitLab users with access levels, admin status, and group memberships
- **Project**: GitLab projects with visibility settings, feature flags, and member lists
- **Namespace/Group**: GitLab groups/namespaces with hierarchical relationships
- **ProjectMembership**: Explicit user-project relationships with access levels
- **GroupMembership**: User-group relationships with inheritance
- **Issue/MergeRequest**: Project resources with ownership and state
### Access Levels
GitLab's hierarchical access system is implemented using numeric levels:
- **Guest** (10): Read-only access to allowed resources
- **Reporter** (20): Can create issues, view CI/CD results
- **Developer** (30): Can push code, create merge requests
- **Maintainer** (40): Can manage project settings and members
- **Owner** (50): Full project control including deletion
### Policy Structure
Cedar policies are organized into separate files by concern:
#### 1. Access Level Policies (`gitlab_simple.cedar`)
- Implements role-based authorization using GitLab's access levels
- Grants permissions based on user access level to projects/groups
- Includes admin override capabilities
- Blocks access for blocked users
- No feature or license checks
#### 2. Visibility Policies (`gitlab_visibility.cedar`)
- Implements GitLab's public/internal/private visibility model
- Allows public access to public projects
- Restricts internal projects to non-external users
- Limits private projects to members only
- Handles archived project restrictions
## REST API Integration
### Request Mapping
REST API requests are mapped to Cedar authorization checks:
```
HTTP Request Cedar Authorization
GET /projects/1 -> can?(User, "read_project", Project::1)
POST /projects/1/issues -> can?(User, "create_issue", Project::1)
PUT /projects/1/settings -> can?(User, "admin_project", Project::1)
DELETE /projects/1 -> can?(User, "destroy_project", Project::1)
```
### Context Variables
HTTP request context is passed to Cedar policies:
- `method`: HTTP method (GET, POST, PUT, DELETE)
- `path`: Request path
- `host`: Request hostname
- `user_agent`: Client user agent
- `ip_address`: Client IP address
### Authorization Flow
1. **Extract Principal**: Identify user from JWT token or API key
2. **Determine Resource**: Extract project/group ID from URL path
3. **Map Action**: Convert HTTP method + path to Cedar action
4. **Build Request**: Create Cedar authorization request
5. **Evaluate**: Execute policies against request
6. **Decision**: Return allow/deny based on policy evaluation
## Entity Generation
### GitLab API Integration
The CLI tool generates Cedar entities by fetching data from GitLab's REST API:
```rust
// Generate entities for a project
let entities = EntitiesRepository::new(api)
.all("gitlab-org/gitlab")
.await?;
```
### Entity Structure
Entities are generated with simplified attributes for policy evaluation:
```json
{
"uid": {"type": "Project", "id": "123"},
"attrs": {
"name": "GitLab",
"path": "gitlab",
"full_path": "gitlab-org/gitlab",
"visibility": "public",
"archived": false,
"members": ["User::\"1\"", "User::\"2\"", "User::\"3\""]
},
"parents": [{"type": "Group", "id": "456"}]
}
```
User entities include access level and status flags:
```json
{
"uid": {"type": "User", "id": "1"},
"attrs": {
"username": "alice",
"access_level": 40,
"admin": false,
"blocked": false,
"external": false
},
"parents": []
}
```
## Implementation Components
### 1. Enhanced GitLab Types
Updated GitLab API types include all fields needed for authorization:
- **Project**: visibility, features, access levels, archived status
- **User**: admin, blocked, external, bot flags
- **Group**: visibility, hierarchy, member access levels
### 2. Cedar Entity Builders
The `GitLabEntityBuilder` converts GitLab API responses to Cedar entities:
```rust
impl GitLabEntityBuilder {
pub fn build_project(project: &Project) -> CedarEntity { ... }
pub fn build_user(user: &User) -> CedarEntity { ... }
pub fn build_membership(user_id: u64, project_id: u64, member: &Member) -> CedarEntity { ... }
}
```
### 3. Authorization Service
The `CedarAuthorizer` evaluates requests against policies:
```rust
pub fn authorize(&self, principal: &str, action: &str, resource: &str, context: &Context) -> Result<Decision> {
let request = Request::new(principal, action, resource, context);
self.authorizer.is_authorized(&request, &self.policies, &self.entities)
}
```
## gRPC Service Design
### Authorization Service
Implement gRPC endpoints that mirror GitLab's `Ability.allowed?` method:
```protobuf
service GitLabAuthorization {
rpc IsAllowed(IsAllowedRequest) returns (IsAllowedResponse);
rpc BatchIsAllowed(BatchIsAllowedRequest) returns (BatchIsAllowedResponse);
}
message IsAllowedRequest {
string user_id = 1;
string action = 2;
string resource_type = 3;
string resource_id = 4;
map<string, string> context = 5;
}
message IsAllowedResponse {
bool allowed = 1;
string reason = 2;
}
```
### Performance Optimizations
- **Entity Caching**: Cache entities in memory with TTL
- **Policy Compilation**: Pre-compile policies for faster evaluation
- **Batch Operations**: Support bulk authorization checks
- **Connection Pooling**: Pool GitLab API connections
## Deployment Patterns
### Standalone PDP
Deploy `authzd` as a standalone authorization service:
- Applications make gRPC calls for authorization decisions
- Entities are refreshed periodically from GitLab API
- Policies are updated via configuration management
### Envoy Integration
Use as Envoy external authorization service:
- Intercept HTTP requests at API gateway
- Make real-time authorization decisions
- Block unauthorized requests before reaching application
### Library Integration
Embed authorization logic in applications:
- Link `authzd` as a Rust library
- Perform in-process authorization checks
- Reduce network latency for high-frequency operations
## Configuration
### Environment Variables
```bash
GITLAB_TOKEN=glpat-xxx # GitLab API token
GITLAB_HOST=gitlab.example.com # GitLab instance URL
AUTHZD_PORT=50051 # gRPC service port
ENTITY_REFRESH_INTERVAL=300 # Seconds between entity updates
POLICY_PATH=/etc/authzd # Path to Cedar policy files
```
### Policy Management
- Store policies in version control
- Use GitOps for policy deployment
- Implement policy validation in CI/CD
- Support hot-reloading of policy changes
## Testing Strategy
### Unit Tests
- Test individual policy rules
- Verify entity generation accuracy
- Validate API type parsing
### Integration Tests
- Test complete authorization flows
- Verify GitLab API integration
- Test gRPC service endpoints
### Policy Tests
- Use Cedar's policy testing framework
- Create test scenarios for common GitLab operations
- Validate policy correctness with real GitLab data
## Security Considerations
### Token Management
- Rotate GitLab API tokens regularly
- Use least-privilege tokens for entity generation
- Secure token storage in production
### Entity Data
- Sanitize sensitive data in entities
- Implement data retention policies
- Audit entity access and modifications
### Policy Security
- Validate policies before deployment
- Implement policy signing/verification
- Monitor for policy conflicts or errors
## Migration Strategy
### Phase 1: Read-Only Operations
- Implement authorization for GET requests
- Test with non-critical projects
- Validate performance and accuracy
### Phase 2: Write Operations
- Add support for POST/PUT/DELETE operations
- Implement fine-grained permissions
- Roll out to production gradually
### Phase 3: Advanced Features
- Add support for custom roles
- Implement audit logging
- Add policy analytics and monitoring
## Monitoring and Observability
### Metrics
- Authorization request rate and latency
- Policy evaluation time
- Entity refresh success/failure rates
- Cache hit/miss ratios
### Logging
- Log all authorization decisions
- Include request context and policy evaluation details
- Implement structured logging for analysis
### Alerting
- Alert on authorization failures
- Monitor entity refresh errors
- Track policy evaluation performance
|