| 328 | } |
| 329 | |
| 330 | func NewAuthorizer(registry prometheus.Registerer) *RegoAuthorizer { |
| 331 | queryOnce.Do(func() { |
| 332 | var err error |
| 333 | query, err = rego.New( |
| 334 | rego.Query("data.authz.allow"), |
| 335 | rego.Module("policy.rego", regoPolicy), |
| 336 | ).PrepareForEval(context.Background()) |
| 337 | if err != nil { |
| 338 | panic(xerrors.Errorf("compile rego: %w", err)) |
| 339 | } |
| 340 | |
| 341 | partialQuery, err = rego.New( |
| 342 | rego.Unknowns([]string{ |
| 343 | "input.object.id", |
| 344 | "input.object.owner", |
| 345 | "input.object.org_owner", |
| 346 | "input.object.acl_user_list", |
| 347 | "input.object.acl_group_list", |
| 348 | }), |
| 349 | rego.Query("data.authz.allow = true"), |
| 350 | rego.Module("policy.rego", regoPolicy), |
| 351 | ).PrepareForPartial(context.Background()) |
| 352 | if err != nil { |
| 353 | panic(xerrors.Errorf("compile partial rego: %w", err)) |
| 354 | } |
| 355 | }) |
| 356 | |
| 357 | // Register metrics to prometheus. |
| 358 | // These bucket values are based on the average time it takes to run authz |
| 359 | // being around 1ms. Anything under ~2ms is OK and does not need to be |
| 360 | // analyzed any further. |
| 361 | buckets := []float64{ |
| 362 | 0.0005, // 0.5ms |
| 363 | 0.001, // 1ms |
| 364 | 0.002, // 2ms |
| 365 | 0.003, |
| 366 | 0.005, |
| 367 | 0.01, // 10ms |
| 368 | 0.02, |
| 369 | 0.035, // 35ms |
| 370 | 0.05, |
| 371 | 0.075, |
| 372 | 0.1, // 100ms |
| 373 | 0.25, // 250ms |
| 374 | 0.75, // 750ms |
| 375 | 1, // 1s |
| 376 | } |
| 377 | |
| 378 | factory := promauto.With(registry) |
| 379 | authorizeHistogram := factory.NewHistogramVec(prometheus.HistogramOpts{ |
| 380 | Namespace: "coderd", |
| 381 | Subsystem: "authz", |
| 382 | Name: "authorize_duration_seconds", |
| 383 | Help: "Duration of the 'Authorize' call in seconds. Only counts calls that succeed.", |
| 384 | Buckets: buckets, |
| 385 | }, []string{"allowed"}) |
| 386 | |
| 387 | prepareHistogram := factory.NewHistogram(prometheus.HistogramOpts{ |