From 3f702084d20b3c3a3ea916f3110e99b22bda60b3 Mon Sep 17 00:00:00 2001 From: Chia Date: Thu, 6 Aug 2026 15:58:57 +1200 Subject: feat: complete commercial developer workflows Add tenant-safe usage observability, prepaid billing controls, API key lifecycle management, Embeddings metering, configurable billing alerts, and resilient provider health propagation. Harden Stripe failure handling, migrations, readiness, and the authenticated control-plane UI with end-to-end verification evidence. --- internal/auth/static.go | 6 +++++- internal/auth/static_test.go | 5 ++++- 2 files changed, 9 insertions(+), 2 deletions(-) (limited to 'internal/auth') diff --git a/internal/auth/static.go b/internal/auth/static.go index 2b44158..67756bf 100644 --- a/internal/auth/static.go +++ b/internal/auth/static.go @@ -27,6 +27,9 @@ type KeyRecord struct { Scopes []string `json:"scopes"` AllowedModels []string `json:"allowed_models,omitempty"` MonthlySpendMicros int64 `json:"monthly_spend_micros,omitempty"` + DailySpendMicros int64 `json:"daily_spend_micros,omitempty"` + RequestsPerMinute int64 `json:"requests_per_minute,omitempty"` + TokensPerMinute int64 `json:"tokens_per_minute,omitempty"` ExpiresAt *time.Time `json:"expires_at,omitempty"` } @@ -78,7 +81,8 @@ func NewStatic(raw string, allowAnonymous bool) (*StaticAuthenticator, error) { hashed = append(hashed, HashedKeyRecord{Hash: hash, Principal: domain.Principal{ KeyID: record.KeyID, TenantID: record.TenantID, ProjectID: record.ProjectID, Scopes: append([]string(nil), record.Scopes...), AllowedModels: allowedModels, - MonthlySpendMicros: record.MonthlySpendMicros, ExpiresAt: record.ExpiresAt, + MonthlySpendMicros: record.MonthlySpendMicros, DailySpendMicros: record.DailySpendMicros, + RequestsPerMinute: record.RequestsPerMinute, TokensPerMinute: record.TokensPerMinute, ExpiresAt: record.ExpiresAt, }}) } if len(hashed) == 0 && !allowAnonymous { diff --git a/internal/auth/static_test.go b/internal/auth/static_test.go index a037ce1..28ca39f 100644 --- a/internal/auth/static_test.go +++ b/internal/auth/static_test.go @@ -78,7 +78,7 @@ func TestStaticAuthenticatorAcceptsAnthropicHeader(t *testing.T) { func TestStaticAuthenticatorLoadsRestrictionsAndRejectsExpiredKey(t *testing.T) { future := time.Now().Add(time.Hour).UTC().Format(time.RFC3339Nano) - authenticator, err := NewStatic(`[{"key":"sk-limited","key_id":"key-1","tenant_id":"tenant-1","project_id":"project-1","allowed_models":["model/allowed"],"monthly_spend_micros":1250000,"expires_at":"`+future+`"}]`, false) + authenticator, err := NewStatic(`[{"key":"sk-limited","key_id":"key-1","tenant_id":"tenant-1","project_id":"project-1","allowed_models":["model/allowed"],"monthly_spend_micros":1250000,"daily_spend_micros":250000,"requests_per_minute":12,"tokens_per_minute":3400,"expires_at":"`+future+`"}]`, false) if err != nil { t.Fatal(err) } @@ -91,6 +91,9 @@ func TestStaticAuthenticatorLoadsRestrictionsAndRejectsExpiredKey(t *testing.T) if principal.MonthlySpendMicros != 1_250_000 { t.Fatalf("monthly spend limit = %d", principal.MonthlySpendMicros) } + if principal.DailySpendMicros != 250_000 || principal.RequestsPerMinute != 12 || principal.TokensPerMinute != 3400 { + t.Fatalf("key spend or rate controls were not loaded: %+v", principal) + } if _, ok := principal.AllowedModels["model/allowed"]; !ok { t.Fatalf("allowed model was not loaded: %+v", principal.AllowedModels) } -- cgit v1.2.3