wip: doctor/cli/docs/api to vector db consolidation; api hardening for descriptions, tenant, and scopes; migrations and conversions of all DALs to EF v10
This commit is contained in:
56
docs/qa/feature-checks/multi-tenant-acceptance-matrix.md
Normal file
56
docs/qa/feature-checks/multi-tenant-acceptance-matrix.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Multi-Tenant Same-Key Acceptance Matrix
|
||||
|
||||
Date: 2026-02-22
|
||||
Source sprint: `SPRINT_20260222_053_DOCS_multi_tenant_same_api_key_contract_baseline.md`
|
||||
Used by sprint: `SPRINT_20260222_060_FE_playwright_multi_tenant_end_to_end_matrix.md`
|
||||
|
||||
## Scope
|
||||
- Validate tenant selection and tenant isolation behavior for:
|
||||
- Platform + Topology APIs
|
||||
- Scanner APIs (scans, triage, webhooks, unknowns)
|
||||
- Graph APIs
|
||||
- Web primary pages with global tenant selector
|
||||
|
||||
## Status Matrix (API)
|
||||
|
||||
| Area | Representative route(s) | Valid tenant | Missing tenant | Cross-tenant attempt | Required evidence |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| Platform context | `/api/v1/platform/context/preferences` | `200` tenant-scoped preferences | deterministic auth/context rejection | `403/404` (tenant mismatch/forbidden) | Command output + payload snippets + test assertion output |
|
||||
| Platform topology | `/api/v1/platform/topology/*` | `200` tenant-scoped topology | deterministic auth/context rejection | `403/404` | Integration test output with overlapping IDs across two tenants |
|
||||
| Scanner scans | `/api/v1/scans/*` | `200/202` for owned scans | deterministic auth/context rejection | `403/404` on non-owned scan id | Test output for scan ownership + replay/read paths |
|
||||
| Scanner triage | `/api/v1/triage/*` | `200` for tenant-owned findings | deterministic auth/context rejection | `404` on non-owned finding id | Test output for triage query/status/isolation cases |
|
||||
| Scanner webhooks | `/api/v1/webhooks/{provider}/{sourceName}` | `2xx` only for tenant-scoped source mapping | `400 tenant_missing` (where required) | deterministic reject/no cross-dispatch | Test output showing same `sourceName` across tenants does not collide |
|
||||
| Scanner unknowns | `/api/v1/unknowns/*` | `200` tenant-scoped list/detail | deterministic auth/context rejection | `404` cross-tenant detail/evidence/history | Test output for unknown detail isolation |
|
||||
| Graph query/search/export | `/api/v1/graph/*` | `200` for authorized tenant + scopes | deterministic auth/context rejection | `403/404` mismatch + ownership denial | Graph API test output with auth + tenant negative paths |
|
||||
|
||||
## Status Matrix (UI Pages)
|
||||
|
||||
| Page group | Routes | Expected tenant indicator behavior | Expected backend call behavior | Negative assertion |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| Mission Control | `/mission-control/*` | Header selector shows selected tenant name and persists after navigation | Requests carry canonical tenant context | No stale content from previous tenant after switch |
|
||||
| Releases | `/releases/*` | Tenant selector remains available; selected tenant stable | Tenant-scoped API calls after switch | No cross-tenant release data visible |
|
||||
| Security | `/security/*` | Selected tenant remains active across subroutes | Scanner/Graph-related requests reflect selected tenant | No findings/advisories leak from previous tenant |
|
||||
| Evidence | `/evidence/*` | Selected tenant persists through refresh | Tenant-scoped evidence requests | No evidence thread from previous tenant persists post-switch |
|
||||
| Ops | `/ops/*` | Tenant context remains globally applied | Platform/ops requests include selected tenant context | No mixed-tenant cards/widgets |
|
||||
| Setup | `/setup/*` | Selector remains visible and stable | Topology/setup reads align with selected tenant where tenant-scoped | No topology entities from previous tenant |
|
||||
| Admin | `/administration/*` (or equivalent admin routes) | Selector persists and selected tenant is clear | Authority admin reads operate in selected tenant scope | No client/user entries leaked from other tenant |
|
||||
|
||||
## Required Artifacts
|
||||
- Tier 2a:
|
||||
- Raw command outputs for Platform/Scanner/Graph targeted verification.
|
||||
- Response/status assertions for valid, missing, and cross-tenant requests.
|
||||
- Tier 2c:
|
||||
- Playwright command output.
|
||||
- Trace zip and screenshots for tenant switch and post-switch navigation checks.
|
||||
- Desktop and mobile viewport results.
|
||||
- Cross-cutting:
|
||||
- Test counts from targeted runs (not suite totals only).
|
||||
- List of new tests written and bugs fixed (if any).
|
||||
- Final go/no-go decision + residual risks.
|
||||
|
||||
## Pass/Fail Gate
|
||||
- Pass:
|
||||
- All matrix rows have deterministic positive and negative-path evidence.
|
||||
- No unresolved cross-tenant leakage failures.
|
||||
- Fail:
|
||||
- Any cross-tenant leakage, nondeterministic auth behavior, or missing Tier 2 evidence blocks rollout.
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,7 @@
|
||||
COMMAND: dotnet run --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -class StellaOps.Authority.Tests.Console.ConsoleAdminEndpointsTests -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Authority.Tests
|
||||
Discovered: StellaOps.Authority.Tests
|
||||
Starting: StellaOps.Authority.Tests
|
||||
Finished: StellaOps.Authority.Tests (ID = '4c6bea7c77eb0f33a99f8646aaddc0e8f692ee0e0fd1a5d9200ec1247d34977b')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Authority.Tests Total: 8, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 1.190s
|
||||
@@ -0,0 +1,7 @@
|
||||
COMMAND: dotnet run --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -method StellaOps.Authority.Tests.Console.ConsoleEndpointsTests.Tenants_ReturnsAllowedTenantAssignments_WithSelectedMarker -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Authority.Tests
|
||||
Discovered: StellaOps.Authority.Tests
|
||||
Starting: StellaOps.Authority.Tests
|
||||
Finished: StellaOps.Authority.Tests (ID = '4c6bea7c77eb0f33a99f8646aaddc0e8f692ee0e0fd1a5d9200ec1247d34977b')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Authority.Tests Total: 1, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 0.315s
|
||||
@@ -0,0 +1,7 @@
|
||||
COMMAND: dotnet run --no-build --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_SelectsRequestedTenant_WhenAssigned -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_Rejects_WhenRequestedTenantNotAssigned -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_Rejects_WhenTenantSelectionIsAmbiguous -method StellaOps.Authority.Tests.OpenIddict.PasswordGrantHandlersTests.ValidatePasswordGrant_SelectsRequestedTenant_WhenAssigned -method StellaOps.Authority.Tests.OpenIddict.PasswordGrantHandlersTests.ValidatePasswordGrant_Rejects_WhenTenantSelectionIsAmbiguous -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_AddsTenantClaim_FromTokenDocument -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_Rejects_WhenTenantDiffersFromToken -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_Rejects_WhenTenantOutsideMultiTenantAssignments -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Authority.Tests
|
||||
Discovered: StellaOps.Authority.Tests
|
||||
Starting: StellaOps.Authority.Tests
|
||||
Finished: StellaOps.Authority.Tests (ID = '4c6bea7c77eb0f33a99f8646aaddc0e8f692ee0e0fd1a5d9200ec1247d34977b')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Authority.Tests Total: 8, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 0.191s
|
||||
@@ -0,0 +1,73 @@
|
||||
[
|
||||
{
|
||||
"name": "authority-admin-tenant-assignments",
|
||||
"command": "dotnet run --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -class StellaOps.Authority.Tests.Console.ConsoleAdminEndpointsTests -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 8,
|
||||
"testsPassed": 8,
|
||||
"evidenceFile": "evidence/authority-console-admin-tenant-assignments.txt"
|
||||
},
|
||||
{
|
||||
"name": "authority-console-tenants-selected-marker",
|
||||
"command": "dotnet run --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -method StellaOps.Authority.Tests.Console.ConsoleEndpointsTests.Tenants_ReturnsAllowedTenantAssignments_WithSelectedMarker -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 1,
|
||||
"testsPassed": 1,
|
||||
"evidenceFile": "evidence/authority-console-tenants-selected-marker.txt"
|
||||
},
|
||||
{
|
||||
"name": "authority-token-tenant-selection-targeted",
|
||||
"command": "dotnet run --no-build --project src/Authority/StellaOps.Authority/StellaOps.Authority.Tests/StellaOps.Authority.Tests.csproj -- -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_SelectsRequestedTenant_WhenAssigned -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_Rejects_WhenRequestedTenantNotAssigned -method StellaOps.Authority.Tests.OpenIddict.ClientCredentialsHandlersTests.ValidateClientCredentials_Rejects_WhenTenantSelectionIsAmbiguous -method StellaOps.Authority.Tests.OpenIddict.PasswordGrantHandlersTests.ValidatePasswordGrant_SelectsRequestedTenant_WhenAssigned -method StellaOps.Authority.Tests.OpenIddict.PasswordGrantHandlersTests.ValidatePasswordGrant_Rejects_WhenTenantSelectionIsAmbiguous -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_AddsTenantClaim_FromTokenDocument -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_Rejects_WhenTenantDiffersFromToken -method StellaOps.Authority.Tests.OpenIddict.TokenValidationHandlersTests.ValidateAccessTokenHandler_Rejects_WhenTenantOutsideMultiTenantAssignments -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 8,
|
||||
"testsPassed": 8,
|
||||
"evidenceFile": "evidence/authority-token-tenant-selection-targeted.txt"
|
||||
},
|
||||
{
|
||||
"name": "platform-targeted-build-attempt",
|
||||
"command": "dotnet run --project src/Platform/__Tests/StellaOps.Platform.WebService.Tests/StellaOps.Platform.WebService.Tests.csproj -- -class StellaOps.Platform.WebService.Tests.PlatformRequestContextResolverTests -class StellaOps.Platform.WebService.Tests.TopologyReadModelEndpointsTests -class StellaOps.Platform.WebService.Tests.ContextEndpointsTests -maxThreads 1 -noLogo",
|
||||
"exitCode": 1,
|
||||
"note": "Failed due to pre-existing unrelated compile errors in src/Policy/StellaOps.Policy.Engine/Endpoints/RiskProfileAirGapEndpoints.cs",
|
||||
"evidenceFile": "evidence/platform-tenant-isolation-targeted.txt"
|
||||
},
|
||||
{
|
||||
"name": "platform-targeted-no-build",
|
||||
"command": "dotnet run --no-build --project src/Platform/__Tests/StellaOps.Platform.WebService.Tests/StellaOps.Platform.WebService.Tests.csproj -- -class StellaOps.Platform.WebService.Tests.PlatformRequestContextResolverTests -class StellaOps.Platform.WebService.Tests.TopologyReadModelEndpointsTests -class StellaOps.Platform.WebService.Tests.ContextEndpointsTests -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 14,
|
||||
"testsPassed": 14,
|
||||
"evidenceFile": "evidence/platform-tenant-isolation-targeted.txt"
|
||||
},
|
||||
{
|
||||
"name": "scanner-targeted-no-build",
|
||||
"command": "dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj -- -class StellaOps.Scanner.WebService.Tests.ScannerRequestContextResolverTests -class StellaOps.Scanner.WebService.Tests.ScannerTenantIsolationAndEndpointRegistrationTests -class StellaOps.Scanner.WebService.Tests.TriageTenantIsolationEndpointsTests -class StellaOps.Scanner.WebService.Tests.UnknownsTenantIsolationEndpointsTests -class StellaOps.Scanner.WebService.Tests.WebhookEndpointsTenantLookupTests -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 13,
|
||||
"testsPassed": 13,
|
||||
"evidenceFile": "evidence/scanner-tenant-isolation-targeted.txt"
|
||||
},
|
||||
{
|
||||
"name": "graph-targeted-no-build",
|
||||
"command": "dotnet run --no-build --project src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj -- -class StellaOps.Graph.Api.Tests.GraphRequestContextResolverTests -class StellaOps.Graph.Api.Tests.GraphTenantAuthorizationAlignmentTests -maxThreads 1 -noLogo",
|
||||
"exitCode": 0,
|
||||
"testsRun": 7,
|
||||
"testsPassed": 7,
|
||||
"evidenceFile": "evidence/graph-tenant-alignment-targeted.txt"
|
||||
},
|
||||
{
|
||||
"name": "web-targeted-unit-suite",
|
||||
"command": "npm run test -- --watch=false --include=src/app/core/auth/tenant-http.interceptor.spec.ts --include=src/app/core/console/console-session.service.spec.ts --include=src/app/core/console/console-session.store.spec.ts --include=src/app/layout/app-topbar/app-topbar.component.spec.ts --include=src/tests/context/platform-context-url-sync.service.spec.ts",
|
||||
"exitCode": 0,
|
||||
"testsRun": 18,
|
||||
"testsPassed": 18,
|
||||
"evidenceFile": "evidence/web-tenant-unit-tests.txt"
|
||||
},
|
||||
{
|
||||
"name": "web-playwright-tenant-matrix",
|
||||
"command": "npm run test:e2e -- tests/e2e/tenant-switch-matrix.spec.ts --workers=1 --trace on --reporter=line",
|
||||
"exitCode": 0,
|
||||
"testsRun": 2,
|
||||
"testsPassed": 2,
|
||||
"evidenceFile": "evidence/web-tenant-playwright-matrix.txt"
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,71 @@
|
||||
COMMAND: dotnet run --no-build --project src/Graph/__Tests/StellaOps.Graph.Api.Tests/StellaOps.Graph.Api.Tests.csproj -- -class StellaOps.Graph.Api.Tests.GraphRequestContextResolverTests -class StellaOps.Graph.Api.Tests.GraphTenantAuthorizationAlignmentTests -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Graph.Api.Tests
|
||||
Discovered: StellaOps.Graph.Api.Tests
|
||||
Starting: StellaOps.Graph.Api.Tests
|
||||
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
|
||||
User profile is available. Using 'C:\Users\VladimirMoushkov\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application started. Press Ctrl+C to shut down.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Hosting environment: Development
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Content root path: C:\dev\New folder\git.stella-ops.org\src\Graph\StellaOps.Graph.Api
|
||||
info: StellaOps.LocalHostname[0]
|
||||
Also accessible at https://graph.stella-ops.local and http://graph.stella-ops.local
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
|
||||
Request starting HTTP/1.1 POST http://localhost/graph/query - application/json;+charset=utf-8 92
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
|
||||
Executing endpoint 'HTTP: POST /graph/query'
|
||||
[AUDIT] 2026-02-22T23:14:43.0954247+00:00 tenant=acme route=/graph/query status=200 scopes=graph:query duration_ms=21
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
|
||||
Executed endpoint 'HTTP: POST /graph/query'
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
|
||||
Request finished HTTP/1.1 POST http://localhost/graph/query - 200 - application/x-ndjson 64.4216ms
|
||||
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
|
||||
User profile is available. Using 'C:\Users\VladimirMoushkov\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application started. Press Ctrl+C to shut down.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Hosting environment: Development
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Content root path: C:\dev\New folder\git.stella-ops.org\src\Graph\StellaOps.Graph.Api
|
||||
info: StellaOps.LocalHostname[0]
|
||||
Also accessible at https://graph.stella-ops.local and http://graph.stella-ops.local
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
|
||||
Request starting HTTP/1.1 POST http://localhost/graph/query - application/json;+charset=utf-8 33
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
|
||||
Executing endpoint 'HTTP: POST /graph/query'
|
||||
info: Microsoft.AspNetCore.Authorization.DefaultAuthorizationService[2]
|
||||
Authorization failed. These requirements were not met:
|
||||
Handler assertion should evaluate to true.
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
|
||||
Executed endpoint 'HTTP: POST /graph/query'
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
|
||||
Request finished HTTP/1.1 POST http://localhost/graph/query - 403 - application/x-ndjson 13.4513ms
|
||||
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[63]
|
||||
User profile is available. Using 'C:\Users\VladimirMoushkov\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application started. Press Ctrl+C to shut down.
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Hosting environment: Development
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Content root path: C:\dev\New folder\git.stella-ops.org\src\Graph\StellaOps.Graph.Api
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[1]
|
||||
Request starting HTTP/1.1 POST http://localhost/graph/query - application/json;+charset=utf-8 33
|
||||
info: StellaOps.LocalHostname[0]
|
||||
Also accessible at https://graph.stella-ops.local and http://graph.stella-ops.local
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
|
||||
Executing endpoint 'HTTP: POST /graph/query'
|
||||
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
|
||||
Executed endpoint 'HTTP: POST /graph/query'
|
||||
info: Microsoft.AspNetCore.Hosting.Diagnostics[2]
|
||||
Request finished HTTP/1.1 POST http://localhost/graph/query - 400 - application/x-ndjson 9.2996ms
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application is shutting down...
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application is shutting down...
|
||||
info: Microsoft.Hosting.Lifetime[0]
|
||||
Application is shutting down...
|
||||
Finished: StellaOps.Graph.Api.Tests (ID = 'a3090b92c822cca46279e2c21530c98d77d6cba006f34ec1c65ccafba9002432')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Graph.Api.Tests Total: 7, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 0.431s
|
||||
@@ -0,0 +1,7 @@
|
||||
COMMAND: dotnet run --no-build --project src/Platform/__Tests/StellaOps.Platform.WebService.Tests/StellaOps.Platform.WebService.Tests.csproj -- -class StellaOps.Platform.WebService.Tests.PlatformRequestContextResolverTests -class StellaOps.Platform.WebService.Tests.TopologyReadModelEndpointsTests -class StellaOps.Platform.WebService.Tests.ContextEndpointsTests -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Platform.WebService.Tests
|
||||
Discovered: StellaOps.Platform.WebService.Tests
|
||||
Starting: StellaOps.Platform.WebService.Tests
|
||||
Finished: StellaOps.Platform.WebService.Tests (ID = '2db881d139343cf28494dcd2d091345dc3546ebd0d3a0f7691cccac253e9eadb')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Platform.WebService.Tests Total: 14, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 1.290s
|
||||
@@ -0,0 +1,77 @@
|
||||
COMMAND: dotnet run --no-build --project src/Scanner/__Tests/StellaOps.Scanner.WebService.Tests/StellaOps.Scanner.WebService.Tests.csproj -- -class StellaOps.Scanner.WebService.Tests.ScannerRequestContextResolverTests -class StellaOps.Scanner.WebService.Tests.ScannerTenantIsolationAndEndpointRegistrationTests -class StellaOps.Scanner.WebService.Tests.TriageTenantIsolationEndpointsTests -class StellaOps.Scanner.WebService.Tests.UnknownsTenantIsolationEndpointsTests -class StellaOps.Scanner.WebService.Tests.WebhookEndpointsTenantLookupTests -maxThreads 1 -noLogo
|
||||
Discovering: StellaOps.Scanner.WebService.Tests
|
||||
Discovered: StellaOps.Scanner.WebService.Tests
|
||||
Starting: StellaOps.Scanner.WebService.Tests
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.9423, Provider=unknown, Error=NotFound
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0794, Provider=unknown, Error=NotFound
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0576, Provider=unknown, Error=NotFound
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0989, Provider=unknown, Error=NotFound
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0406, Provider=unknown, Error=NotFound
|
||||
[01:14:33 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0236, Provider=unknown, Error=NotFound
|
||||
[01:14:33 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:33 INF] Hosting environment: Testing
|
||||
[01:14:33 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:33 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0731, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0396, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0261, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0853, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.039, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0271, Provider=unknown, Error=NotFound
|
||||
[01:14:34 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:34 INF] Hosting environment: Testing
|
||||
[01:14:34 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:34 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0652, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0364, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.023, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.098, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0402, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0257, Provider=unknown, Error=NotFound
|
||||
[01:14:34 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:34 INF] Hosting environment: Testing
|
||||
[01:14:34 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:34 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.059, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0342, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0205, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0908, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.041, Provider=unknown, Error=NotFound
|
||||
[01:14:34 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0239, Provider=unknown, Error=NotFound
|
||||
[01:14:35 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:35 INF] Hosting environment: Testing
|
||||
[01:14:35 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:35 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0633, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0328, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.02, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0977, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0401, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0226, Provider=unknown, Error=NotFound
|
||||
[01:14:35 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:35 INF] Hosting environment: Testing
|
||||
[01:14:35 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:35 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0554, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0304, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0224, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0834, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0344, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0329, Provider=unknown, Error=NotFound
|
||||
[01:14:35 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:35 INF] Hosting environment: Testing
|
||||
[01:14:35 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:35 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0767, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0523, Provider=unknown, Error=NotFound
|
||||
[01:14:35 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0313, Provider=unknown, Error=NotFound
|
||||
[01:14:36 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=cas-access, Name=default, Success=False, ElapsedMs=0.0995, Provider=unknown, Error=NotFound
|
||||
[01:14:36 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=registry, Name=default, Success=False, ElapsedMs=0.0499, Provider=unknown, Error=NotFound
|
||||
[01:14:36 WRN] Surface secret access: Component=Scanner.Worker, Tenant=tenant-a, RequestComponent=Scanner.WebService, SecretType=attestation, Name=default, Success=False, ElapsedMs=0.0383, Provider=unknown, Error=NotFound
|
||||
[01:14:36 INF] Application started. Press Ctrl+C to shut down.
|
||||
[01:14:36 INF] Hosting environment: Testing
|
||||
[01:14:36 INF] Content root path: C:\dev\New folder\git.stella-ops.org\src\Scanner\StellaOps.Scanner.WebService
|
||||
[01:14:36 INF] Also accessible at https://scanner.stella-ops.local and http://scanner.stella-ops.local
|
||||
Finished: StellaOps.Scanner.WebService.Tests (ID = 'f93c0ca5bc3341a3dfa74a04e79e09dc2be5a4321b76509e45c0be50c80444ab')
|
||||
=== TEST EXECUTION SUMMARY ===
|
||||
StellaOps.Scanner.WebService.Tests Total: 13, Errors: 0, Failed: 0, Skipped: 0, Not Run: 0, Time: 3.398s
|
||||
@@ -0,0 +1,25 @@
|
||||
COMMAND: npm run test:e2e -- tests/e2e/tenant-switch-matrix.spec.ts --workers=1 --trace on --reporter=line
|
||||
|
||||
> stellaops-web@0.0.0 test:e2e
|
||||
> playwright test tests/e2e/tenant-switch-matrix.spec.ts --workers=1 --trace on --reporter=line
|
||||
|
||||
|
||||
Running 2 tests using 1 worker
|
||||
|
||||
|
||||
node.exe : [1A[2K(node:61160) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
At line:1 char:1
|
||||
+ & "C:\Program Files\nodejs/node.exe" "C:\Users\VladimirMoushkov\AppDa ...
|
||||
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
+ CategoryInfo : NotSpecified: ([1A[2K(node:6... env being set.:String) [], RemoteException
|
||||
+ FullyQualifiedErrorId : NativeCommandError
|
||||
|
||||
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
[1A[2K(node:61160) Warning: The 'NO_COLOR' env is ignored due to the 'FORCE_COLOR' env being set.
|
||||
(Use `node --trace-warnings ...` to show where the warning was created)
|
||||
|
||||
|
||||
[1A[2K[1/2] tests\e2e\tenant-switch-matrix.spec.ts:9:7 › Multi-tenant switch matrix › switches tenant from header and persists across primary sections (desktop)
|
||||
[1A[2K[2/2] tests\e2e\tenant-switch-matrix.spec.ts:41:7 › Multi-tenant switch matrix › keeps tenant selector usable and persistent on mobile viewport
|
||||
[1A[2K 2 passed (29.9s)
|
||||
@@ -0,0 +1,67 @@
|
||||
COMMAND: npm run test -- --watch=false --include=src/app/core/auth/tenant-http.interceptor.spec.ts --include=src/app/core/console/console-session.service.spec.ts --include=src/app/core/console/console-session.store.spec.ts --include=src/app/layout/app-topbar/app-topbar.component.spec.ts --include=src/tests/context/platform-context-url-sync.service.spec.ts
|
||||
|
||||
> stellaops-web@0.0.0 test
|
||||
> ng test --watch=false --watch=false --include=src/app/core/auth/tenant-http.interceptor.spec.ts --include=src/app/core/console/console-session.service.spec.ts --include=src/app/core/console/console-session.store.spec.ts --include=src/app/layout/app-topbar/app-topbar.component.spec.ts --include=src/tests/context/platform-context-url-sync.service.spec.ts
|
||||
|
||||
❯ Building...
|
||||
✔ Building...
|
||||
Initial chunk files | Names | Raw size
|
||||
spec-app-layout-app-topbar-app-topbar.component.js | spec-app-layout-app-topbar-app-topbar.component | 373.21 kB |
|
||||
styles.css | styles | 208.77 kB |
|
||||
chunk-TT2M2B6M.js | - | 23.09 kB |
|
||||
chunk-4HW7O5MC.js | - | 19.31 kB |
|
||||
chunk-BABPRG6R.js | - | 11.55 kB |
|
||||
spec-tests-context-platform-context-url-sync.service.js | spec-tests-context-platform-context-url-sync.service | 11.15 kB |
|
||||
chunk-PIZBSUX3.js | - | 9.12 kB |
|
||||
spec-app-core-console-console-session.service.js | spec-app-core-console-console-session.service | 8.04 kB |
|
||||
chunk-XNDA3IA4.js | - | 5.67 kB |
|
||||
chunk-XPWKAQFU.js | - | 5.20 kB |
|
||||
spec-app-core-auth-tenant-http.interceptor.js | spec-app-core-auth-tenant-http.interceptor | 4.86 kB |
|
||||
spec-app-core-console-console-session.store.js | spec-app-core-console-console-session.store | 3.75 kB |
|
||||
init-testbed.js | init-testbed | 1.27 kB |
|
||||
polyfills.js | polyfills | 121 bytes |
|
||||
|
||||
| Initial total | 685.10 kB
|
||||
|
||||
Application bundle generation complete. [33.235 seconds] - 2026-02-22T23:16:31.084Z
|
||||
|
||||
node.exe : ▲ [WARNING] NG8113: GateSimulationResultsComponent is not used within the template of BundleSimulatorComponent [plugin angular-compiler]
|
||||
At line:1 char:1
|
||||
+ & "C:\Program Files\nodejs/node.exe" "C:\Users\VladimirMoushkov\AppDa ...
|
||||
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
+ CategoryInfo : NotSpecified: (▲ [WARNING] NG8...gular-compiler]:String) [], RemoteException
|
||||
+ FullyQualifiedErrorId : NativeCommandError
|
||||
|
||||
|
||||
src/app/features/policy-gates/components/bundle-simulator/bundle-simulator.component.ts:26:38:
|
||||
26 │ ...ports: [ProfileSelectorComponent, GateSimulationResultsComponent],
|
||||
╵ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
|
||||
|
||||
RUN v4.0.18 C:/dev/New folder/git.stella-ops.org/src/Web/StellaOps.Web
|
||||
|
||||
✓ |stellaops-web| src/app/core/console/console-session.store.spec.ts (4 tests) 6ms
|
||||
stderr | src/app/core/console/console-session.service.spec.ts > ConsoleSessionService > rolls back tenant switch when tenant context load fails
|
||||
Failed to load console context Error: tenant tenant-default is not available
|
||||
at C:/dev/New folder/git.stella-ops.org/src/Web/StellaOps.Web/src/app/core/console/console-session.service.spec.ts:47:31
|
||||
at Observable.init [as _subscribe] (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\observable\throwError.js:8:64)
|
||||
at Observable._trySubscribe (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\Observable.js:41:25)
|
||||
at C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\Observable.js:35:31
|
||||
at Object.errorContext (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\util\errorContext.js:22:9)
|
||||
at Observable.subscribe (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\Observable.js:26:24)
|
||||
at C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\firstValueFrom.js:24:16
|
||||
at new ZoneAwarePromise (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\zone.js\fesm2015\zone.js:2701:25)
|
||||
at firstValueFrom (C:\dev\New folder\git.stella-ops.org\src\Web\StellaOps.Web\node_modules\rxjs\dist\cjs\internal\firstValueFrom.js:8:12)
|
||||
at _ConsoleSessionService.<anonymous> (C:/dev/New folder/git.stella-ops.org/src/Web/StellaOps.Web/src/app/core/console/console-session.service.ts:51:36)
|
||||
|
||||
✓ |stellaops-web| src/app/core/console/console-session.service.spec.ts (4 tests) 31ms
|
||||
✓ |stellaops-web| src/app/core/auth/tenant-http.interceptor.spec.ts (4 tests) 31ms
|
||||
✓ |stellaops-web| src/tests/context/platform-context-url-sync.service.spec.ts (3 tests) 112ms
|
||||
✓ |stellaops-web| src/app/layout/app-topbar/app-topbar.component.spec.ts (3 tests) 198ms
|
||||
|
||||
Test Files 5 passed (5)
|
||||
Tests 18 passed (18)
|
||||
Start at 01:16:31
|
||||
Duration 1.92s (transform 1.25s, setup 2.19s, import 1.28s, tests 378ms, environment 3.94s)
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"feature": "multi-tenant-same-api-key-selection",
|
||||
"runId": "run-001",
|
||||
"capturedAtUtc": "2026-02-22T23:18:33Z",
|
||||
"decision": "go",
|
||||
"rationale": [
|
||||
"Tier 2a targeted API verification passed for Authority, Platform, Scanner, and Graph (51/51).",
|
||||
"Tier 2c Playwright tenant-switch matrix passed for desktop and mobile (2/2).",
|
||||
"Frontend targeted tenant unit/component tests passed (18/18)."
|
||||
],
|
||||
"residualRisks": [
|
||||
"An unrelated pre-existing compile break exists in Policy (RiskProfileAirGapEndpoints RequireStellaOpsScopes missing); it does not affect tenant test slices run with --no-build but should be fixed before broad solution builds.",
|
||||
"Playwright matrix currently covers first-level page groups; deeper page-level permutations remain outside this sprint evidence scope."
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
{
|
||||
"type": "api",
|
||||
"module": "multi-tenant",
|
||||
"feature": "same-api-key-selection",
|
||||
"runId": "run-001",
|
||||
"capturedAtUtc": "2026-02-22T23:18:33Z",
|
||||
"transport": "xUnit v3 in-process API integration via dotnet run",
|
||||
"checks": [
|
||||
{
|
||||
"service": "authority",
|
||||
"scope": "admin client assignment CRUD",
|
||||
"testsRun": 8,
|
||||
"testsPassed": 8,
|
||||
"evidenceFile": "evidence/authority-console-admin-tenant-assignments.txt",
|
||||
"behaviorVerified": [
|
||||
"Create and update admin client endpoints persist multi-tenant assignments.",
|
||||
"Duplicate, missing, and invalid tenant assignment payloads are rejected deterministically.",
|
||||
"Audit event properties include before/after tenant assignment fields."
|
||||
],
|
||||
"result": "pass"
|
||||
},
|
||||
{
|
||||
"service": "authority",
|
||||
"scope": "console tenants selected marker",
|
||||
"testsRun": 1,
|
||||
"testsPassed": 1,
|
||||
"evidenceFile": "evidence/authority-console-tenants-selected-marker.txt",
|
||||
"behaviorVerified": [
|
||||
"/console/tenants returns assigned tenant set and selectedTenant marker for immediate UI hydration."
|
||||
],
|
||||
"result": "pass"
|
||||
},
|
||||
{
|
||||
"service": "authority",
|
||||
"scope": "token issuance and validation tenant selection",
|
||||
"testsRun": 8,
|
||||
"testsPassed": 8,
|
||||
"evidenceFile": "evidence/authority-token-tenant-selection-targeted.txt",
|
||||
"behaviorVerified": [
|
||||
"Client credentials and password grants select requested tenant when assigned.",
|
||||
"Ambiguous or unassigned tenant selections are rejected.",
|
||||
"Access token validation rejects tenant mismatch and out-of-assignment tenant claims."
|
||||
],
|
||||
"result": "pass"
|
||||
},
|
||||
{
|
||||
"service": "platform",
|
||||
"scope": "resolver + topology + context endpoints",
|
||||
"testsRun": 14,
|
||||
"testsPassed": 14,
|
||||
"evidenceFile": "evidence/platform-tenant-isolation-targeted.txt",
|
||||
"behaviorVerified": [
|
||||
"Resolver returns tenant_missing and tenant_conflict errors deterministically.",
|
||||
"Topology endpoints return bad request when tenant header is missing.",
|
||||
"Topology and context data are isolated across tenants with overlapping identifiers."
|
||||
],
|
||||
"result": "pass"
|
||||
},
|
||||
{
|
||||
"service": "scanner",
|
||||
"scope": "resolver + scans + triage + unknowns + webhook lookup",
|
||||
"testsRun": 13,
|
||||
"testsPassed": 13,
|
||||
"evidenceFile": "evidence/scanner-tenant-isolation-targeted.txt",
|
||||
"behaviorVerified": [
|
||||
"Resolver returns deterministic missing/conflict outcomes with canonical and legacy headers.",
|
||||
"Cross-tenant scan status, triage evidence, and callgraph submission attempts are rejected.",
|
||||
"Webhook source resolution is tenant-scoped and same sourceName collisions do not cross-dispatch."
|
||||
],
|
||||
"result": "pass"
|
||||
},
|
||||
{
|
||||
"service": "graph",
|
||||
"scope": "tenant resolver + authorization alignment",
|
||||
"testsRun": 7,
|
||||
"testsPassed": 7,
|
||||
"evidenceFile": "evidence/graph-tenant-alignment-targeted.txt",
|
||||
"observedHttpStatuses": [
|
||||
"200",
|
||||
"400",
|
||||
"403"
|
||||
],
|
||||
"behaviorVerified": [
|
||||
"Canonical tenant header + scope yields success for query path.",
|
||||
"Conflicting tenant headers produce tenant_conflict/bad request behavior.",
|
||||
"Missing required scope returns forbidden deterministically."
|
||||
],
|
||||
"result": "pass"
|
||||
}
|
||||
],
|
||||
"summary": {
|
||||
"testsRun": 51,
|
||||
"testsPassed": 51,
|
||||
"testsFailed": 0,
|
||||
"crossTenantAttemptsDenied": true
|
||||
},
|
||||
"verdict": "pass"
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
{
|
||||
"tier": 2,
|
||||
"check": "ui-verification",
|
||||
"feature": "multi-tenant-same-api-key-selection",
|
||||
"runId": "run-001",
|
||||
"timestamp": "2026-02-22T23:18:33Z",
|
||||
"result": "pass",
|
||||
"specFile": "tests/e2e/tenant-switch-matrix.spec.ts",
|
||||
"testCount": 2,
|
||||
"passCount": 2,
|
||||
"failCount": 0,
|
||||
"pageMatrix": [
|
||||
"mission-control",
|
||||
"releases",
|
||||
"security",
|
||||
"evidence",
|
||||
"ops",
|
||||
"setup",
|
||||
"administration"
|
||||
],
|
||||
"viewports": [
|
||||
"desktop",
|
||||
"mobile"
|
||||
],
|
||||
"assertions": [
|
||||
"Tenant selector switches tenant and keeps selected tenant visible in header.",
|
||||
"Tenant selection persists across primary section navigation and page reload.",
|
||||
"Network requests captured by fixture include selected tenant header context after switch."
|
||||
],
|
||||
"artifacts": {
|
||||
"evidenceFile": "evidence/web-tenant-playwright-matrix.txt",
|
||||
"traceFiles": [
|
||||
"artifacts/playwright-traces/tenant-switch-matrix-Multi-8557c-s-primary-sections-desktop-.trace.zip",
|
||||
"artifacts/playwright-traces/tenant-switch-matrix-Multi-a4393-rsistent-on-mobile-viewport.trace.zip"
|
||||
]
|
||||
},
|
||||
"notes": "Desktop and mobile tenant switch matrix passed with deterministic fixtures for tenant-alpha and tenant-bravo."
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
{
|
||||
"name": "web-playwright-tenant-matrix-expanded",
|
||||
"command": "npx playwright test tests/e2e/tenant-switch-matrix.spec.ts --reporter=list",
|
||||
"exitCode": 0,
|
||||
"testsRun": 10,
|
||||
"testsPassed": 10,
|
||||
"evidenceFile": "evidence/web-tenant-playwright-matrix-expanded.txt"
|
||||
}
|
||||
]
|
||||
Binary file not shown.
@@ -0,0 +1,35 @@
|
||||
{
|
||||
"tier": 2,
|
||||
"check": "ui-verification",
|
||||
"feature": "multi-tenant-same-api-key-selection",
|
||||
"runId": "run-002",
|
||||
"timestamp": "2026-02-23T05:45:43Z",
|
||||
"result": "pass",
|
||||
"specFile": "tests/e2e/tenant-switch-matrix.spec.ts",
|
||||
"testCount": 10,
|
||||
"passCount": 10,
|
||||
"failCount": 0,
|
||||
"pageMatrix": [
|
||||
"mission-control",
|
||||
"releases",
|
||||
"security",
|
||||
"evidence",
|
||||
"ops",
|
||||
"setup",
|
||||
"administration"
|
||||
],
|
||||
"viewports": [
|
||||
"desktop",
|
||||
"mobile"
|
||||
],
|
||||
"assertions": [
|
||||
"Tenant selector switches to selected tenant and remains visible across section navigation.",
|
||||
"Each primary page route preserves the selected tenant and renders expected section markers.",
|
||||
"Captured tenant-scoped API calls never leak to a different tenant during switch and reverse-switch flows."
|
||||
],
|
||||
"artifacts": {
|
||||
"evidenceFile": "evidence/web-tenant-playwright-matrix-expanded.txt",
|
||||
"traceFiles": []
|
||||
},
|
||||
"notes": "Expanded matrix now covers 10 Playwright scenarios including per-section route assertions and bidirectional tenant switching."
|
||||
}
|
||||
Reference in New Issue
Block a user