feat: auth hardening — scope enforcement, tenant isolation, and docs
All checks were successful
CI / build (push) Successful in 38s
CI / docker (push) Successful in 39s

Add @PreAuthorize annotations to all API controllers (14 endpoints
across 6 controllers) enforcing OAuth2 scopes: apps:manage, apps:deploy,
billing:manage, observe:read, platform:admin.

Enforce tenant isolation: TenantResolutionFilter now rejects cross-tenant
access on /api/tenants/{id}/* paths. New TenantOwnershipValidator checks
environment/app ownership for paths without tenantId. Platform admins
bypass both layers.

Fix frontend: OrgResolver split into two useEffect hooks so scopes
refresh on org switch. Scopes now served from /api/config (single source
of truth). Bootstrap cleaned — standalone org permissions removed.

Update docs/architecture.md, docs/user-manual.md, and CLAUDE.md to
reflect all auth hardening changes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
hsiegeln
2026-04-05 15:32:53 +02:00
parent b459a69083
commit 051f7fdae9
21 changed files with 408 additions and 136 deletions

View File

@@ -2,6 +2,7 @@ interface AppConfig {
logtoEndpoint: string;
logtoClientId: string;
logtoResource: string;
scopes: string[];
}
let cached: AppConfig | null = null;
@@ -24,6 +25,18 @@ export async function fetchConfig(): Promise<AppConfig> {
logtoEndpoint: import.meta.env.VITE_LOGTO_ENDPOINT || 'http://localhost:3001',
logtoClientId: import.meta.env.VITE_LOGTO_CLIENT_ID || '',
logtoResource: import.meta.env.VITE_LOGTO_RESOURCE || '',
scopes: [
'platform:admin',
'tenant:manage',
'billing:manage',
'team:manage',
'apps:manage',
'apps:deploy',
'secrets:manage',
'observe:read',
'observe:debug',
'settings:manage',
],
};
return cached;
}