mirror of
https://github.com/azaion/admin.git
synced 2026-06-21 20:01:08 +00:00
f369153149
Batch 5 (cycle 2 hotfix sprint, batch 1 of 2). 6 story points under epic AZ-530. Addresses 2 Critical + 2 High deploy-blocking findings from security_report_cycle2.md (F-INFRA-1..F-INFRA-4). AZ-552 — drop_jwt_secret_deploy_preflight (1 pt, F-INFRA-1 Critical) scripts/start-services.sh swaps obsolete JwtConfig__Secret preflight for the cycle-2 trio (KeysFolder + ActiveKid + DataProtection.KeysFolder). .env.example, env/api/env.ps1, _docs/04_deploy/* updated to match. Repo scan in scripts/ and .env.example returns 0 offenders. AZ-553 — bind_mount_es256_keys (2 pts, F-INFRA-2 Critical) start-services.sh bind-mounts DEPLOY_HOST_JWT_KEYS_DIR read-only at /etc/azaion/jwt-keys; preflight fails fast on a missing or empty host directory with operator-actionable error messages. AZ-554 — persist_dataprotection_keys (2 pts, F-INFRA-3 High) Program.cs DataProtection wiring now fails fast in Production when KeysFolder is unset OR not probe-writable. start-services.sh bind-mounts DEPLOY_HOST_DP_KEYS_DIR read-write at /var/lib/azaion/dp-keys. Development behaviour unchanged (ephemeral default). AZ-555 — secrets_readme_es256_rewrite (1 pt, F-INFRA-4 High) secrets/README.md schema fully rewritten; new "Host-side directories" subsection with bind-mount table + ownership/permission guidance. Cycle-1 JwtConfig__Secret removed from live schema (one prose deprecation paragraph retained). Adjacent hygiene module-layout.md "Owns" extended to include scripts/, secrets/, env/, .env.example (gap from Step 9 new-task layout-delta). Tests e2e/Azaion.E2E/Tests/Cycle2HotfixDeployTests.cs — 19 facts (8 exec, 11 Skip with rationale per AZ-537/AZ-538 precedent). Skipped tests cover preflight/restart/Production-only paths verified at deploy gate. Build: 0W 0E across Azaion.AdminApi + Azaion.E2E. Test run deferred to autodev Step 11 (Run Tests). Tracker transition deferred to next batch (MCP availability unverified in this session — Leftovers pattern). Co-authored-by: Cursor <cursoragent@cursor.com>
7.5 KiB
7.5 KiB
Module Layout
Language: csharp
Layout Convention: solution-flat (legacy — pre-src/ convention)
Root: ./ (csproj folders sit at workspace root)
Last Updated: 2026-05-14 (cycle 2 Auth Modernization AZ-531..AZ-538; cycle-2 hotfix AZ-552..AZ-557 added scripts/, secrets/, env/, .env.example to Admin API Owns)
Layout Rules
- This admin/ workspace is one deployable (the
Azaion.AdminApiHTTP service) split across three production csproj projects + one e2e test csproj:Azaion.AdminApi,Azaion.Services,Azaion.Common,e2e/Azaion.E2E. (TheAzaion.Testunit-test project was removed in cycle 2 once its only test class —SecurityTest.cs— was deleted along with the encrypted-download stack; no in-process unit tests remain.) - Existing task specs (
_docs/02_tasks/*/AZ-*.md) all useComponent: Admin APIas a single coarse identifier covering this entire workspace. The Per-Component Mapping below honors that convention rather than rewriting every task spec. - The conceptual sub-components documented in
_docs/02_document/components/01_data_layer..05_admin_api/are read-time documentation aids, not write-time ownership boundaries. They are listed under "Conceptual Sub-Components" below for reference only. - Public API surface = the namespaces / interfaces exposed across csproj boundaries (
I*Serviceinterfaces inAzaion.Services, request DTOs inAzaion.Common/Requests/, entities inAzaion.Common/Entities/). - Tests live in
e2e/Azaion.E2E/(HTTP black-box). Production code never imports from there.
Per-Component Mapping
Component: Admin API
- Epic: AZ-181 (and any other admin-API epic, e.g. AZ-509 for the Detection Classes feature)
- Directory: workspace root (multi-csproj, see below)
- Owns (exclusive write during implementation):
Azaion.AdminApi/**Azaion.Services/**Azaion.Common/**e2e/Azaion.E2E/**(xUnit/HttpClient-based black-box tests)e2e/db-init/**(test-DB seed/init scripts consumed by the e2e harness)docker-compose.test.ymlscripts/**(deploy / lifecycle bash helpers — workspace-root infra)secrets/**(sops + age handover, public env overlays, jwt-keys host dir)env/**(DB schema/install scripts, dev convenience env setters).env.example(operator-facing runtime env template)
- Public API (visible to other csprojs within the workspace):
Azaion.Services/I*Service.csinterfaces (UserService, AuthService, ResourcesService, …)Azaion.Services/Security.cs,Azaion.Services/Cache.cs(used byAzaion.AdminApi/Program.cs)Azaion.Common/Requests/*request DTOsAzaion.Common/Entities/*linq2db entitiesAzaion.Common/Database/*IDbFactory+ connection helpersAzaion.Common/Configs/*strongly-typed config recordsAzaion.Common/Extensions/*extension methodsAzaion.Common/BusinessException.csAzaion.AdminApi/Program.cs(composition root + minimal-API endpoints)Azaion.AdminApi/BusinessExceptionHandler.cs
- Internal (do NOT import across csproj boundaries):
- private/internal members within each csproj (default C# visibility rules apply)
Azaion.AdminApi/appsettings*.json(loaded by the host, not imported)e2e/Azaion.E2E/Helpers/*(test-only helpers, never imported by production)
- Imports from: (none — this is the only deployable in the workspace; the Loader is architecturally retired per
suite/_docs/_repo-config.yamlunresolved:loader-retirement-arch-doc) - Consumed by: HTTP clients (UI workspace, edge services on secured Jetson, SaaS browser sessions) — out of process
Conceptual Sub-Components (documentation only — NOT ownership boundaries)
These come from _docs/02_document/components/ and exist for reading the codebase, not for assigning task ownership. A single task may legitimately touch multiple sub-components within the Admin API umbrella.
| # | Sub-component | Primary file locations |
|---|---|---|
| 1 | Data Layer | Azaion.Common/Database/, Azaion.Common/Configs/ (incl. cycle-2 AuthConfig.cs + JwtConfig.cs rebuilt for ES256 + new SessionConfig), Azaion.Common/Entities/ (incl. cycle-1 DetectionClass.cs; cycle-2 Session.cs + AuditEvent.cs; User.cs extended with lockout + MFA columns; RoleEnum.cs + Service = 60) |
| 2 | User Management | Azaion.Services/UserService.cs (cycle-2 — Argon2id verify/hash + lazy migration + lockout + per-account rate-limit checks; new dependencies on IAuditLog, IOptions<AuthConfig>), Azaion.Common/Requests/Register{User,DeviceResponse}.cs, LoginRequest.cs, LoginResponse.cs (new — AZ-531), MfaRequests.cs (new — AZ-534), MissionSessionRequest.cs (new — AZ-533), SetUserQueueOffsetsRequest.cs |
| 3 | Auth & Security | Azaion.Services/AuthService.cs (cycle-2 — ES256 + AccessToken record + sid/jti/amr claims), Azaion.Services/Security.cs (cycle-2 — Argon2id HashPassword/VerifyPassword; ToHash deleted), Azaion.Services/RefreshTokenService.cs (new — AZ-531), Azaion.Services/SessionService.cs (new — AZ-535), Azaion.Services/MfaService.cs (new — AZ-534), Azaion.Services/MissionTokenService.cs (new — AZ-533), Azaion.Services/JwtSigningKeyProvider.cs (new — AZ-532), Azaion.Services/AuditLog.cs (new — AZ-537), Azaion.Services/Cache.cs |
| 4 | Resource Management | Azaion.Services/ResourcesService.cs (GetResourceRequest.cs removed in cycle 2 with POST /resources/get; SetHWRequest.cs removed by AZ-197; ResourceUpdateService.cs + GetUpdateRequest.cs + PublishResourceRequest.cs removed when AZ-183 was reverted) |
| 4b | Detection Classes | Azaion.Services/DetectionClassService.cs + Azaion.Common/Requests/{Create,Update}DetectionClassRequest.cs (added cycle 1 / AZ-513) |
| 5 | Admin API (HTTP) | Azaion.AdminApi/Program.cs (cycle-2 — significantly expanded: HSTS / HTTPS redirect, RateLimiter, DataProtection, eight new endpoints, IssueDualTokens + ParseSidClaim/ParseUserIdClaim helpers), Azaion.AdminApi/BusinessExceptionHandler.cs (cycle-2 — per-enum status mapping + Retry-After header), Azaion.AdminApi/appsettings*.json |
Allowed Dependencies (csproj layering)
| Layer | csproj | May reference |
|---|---|---|
| 4. Entry / Host | Azaion.AdminApi |
Azaion.Services, Azaion.Common |
| 3. Application | Azaion.Services |
Azaion.Common |
| 2. Foundation | Azaion.Common |
(none) |
| —. Tests (out-of-process e2e) | e2e/Azaion.E2E |
(none from production csprojs — HTTP only) |
A reference from a lower production layer to a higher production layer is an Architecture finding (High severity) in /code-review Phase 7. Test projects may reference any production csproj; production csprojs may NOT reference test projects.
Layout Conventions (reference)
| Language | Root | Per-component path | Public API file | Test path |
|---|---|---|---|---|
| C# (.NET) | ./ (this workspace, legacy flat layout) |
./<Csproj>/ |
namespace-root types in each csproj | e2e/Azaion.E2E/ |
Notes
- This file was authored 2026-05-13 by
/autodevStep 10 to satisfy/implementStep 4. The_docs/artifact set predates the Step 1.5 module-layout addition, so this is a backfill rather than a fresh decompose Step 1.5 run. - If the project later splits into multiple deployables (e.g. carving out
Azaion.AnnotationsApi), re-run/decomposeStep 1.5 to produce a finer-grained mapping.