Files
admin/_docs/02_document/modules/admin_api_program.md
T
Oleksandr Bezdieniezhnykh 3a925b9b0f
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status
refactor: remove obsolete resource download and installer endpoints
- Deleted the `POST /resources/get/{dataFolder?}` and `GET /resources/get-installer` endpoints as part of the architectural shift towards simplified resource management.
- Removed associated methods and configurations, including `ResourcesService.GetEncryptedResource`, `ResourcesService.GetInstaller`, and related properties in `ResourcesConfig`.
- Cleaned up environment variables and configuration files to reflect the removal of installer-related settings.
- Eliminated the `GetResourceRequest` DTO and its validator, along with the `WrongResourceName` error code.
- Updated documentation to clarify the changes in resource handling and the retirement of per-user file encryption.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-14 04:17:55 +03:00

6.3 KiB

Module: Azaion.AdminApi.Program

Purpose

Application entry point: configures DI, middleware, authentication, authorization, CORS, Swagger, logging, and defines all HTTP endpoints using ASP.NET Core Minimal API.

Public Interface (HTTP Endpoints)

Cycle 1 (2026-05-13) note — endpoint surface changed by AZ-513 (detection-class CRUD), AZ-196 (device auto-registration), AZ-197 (hardware-binding removal). AZ-183 (OTA update check + publish) was reverted later the same day after the security audit (finding F-1) — the OTA delivery model itself was deemed obsolete; see _docs/05_security/security_report.md for context. The table reflects the post-cycle-1 state including that revert.

Cycle 2 (2026-05-14) note — three more endpoints were removed as obsolete: POST /resources/get/{dataFolder?}, GET /resources/get-installer, GET /resources/get-installer/stage. The encrypted-download support stack (Security.GetApiEncryptionKey / EncryptTo / DecryptTo, ResourcesService.GetEncryptedResource / GetInstaller, GetResourceRequest DTO, WrongResourceName = 50 enum value, ResourcesConfig.SuiteInstallerFolder / SuiteStageInstallerFolder) went with them. ADR-003 in architecture.md was retired in the same change.

Method Path Auth Summary Cycle 1 origin
POST /login Anonymous Validates credentials, returns JWT token
POST /users ApiAdmin Creates a new user
POST /devices ApiAdmin Creates a CompanionPC device user (auto serial / email / 32-hex password) AZ-196
GET /users/current Any authenticated Returns current user from JWT claims
GET /users ApiAdmin Lists users with optional email/role filters
PUT /users/queue-offsets/set Any authenticated Updates user's queue offsets
PUT /users/{email}/set-role/{role} ApiAdmin Changes a user's role
PUT /users/{email}/enable ApiAdmin Enables a user account
PUT /users/{email}/disable ApiAdmin Disables a user account
DELETE /users/{email} ApiAdmin Removes a user
POST /resources/{dataFolder?} Any authenticated Uploads a resource file
GET /resources/list/{dataFolder?} Any authenticated Lists files in a resource folder
POST /resources/clear/{dataFolder?} ApiAdmin Clears a resource folder
POST /classes ApiAdmin Creates a detection class AZ-513
PATCH /classes/{id:int} ApiAdmin Updates a detection class (partial-merge) AZ-513
DELETE /classes/{id:int} ApiAdmin Deletes a detection class AZ-513

Removed endpoints

The following endpoints have been removed and now return 404:

Method Path Removed in Reason
PUT /users/hardware/set cycle 1 (AZ-197) hardware-binding feature deleted (no fielded clients in target architecture)
POST /resources/check cycle 1 (AZ-197) was the hardware-binding side-effect probe; no remaining purpose
POST /get-update post-cycle-1 (AZ-183 reverted) security audit F-1: endpoint disclosed plaintext per-resource encryption keys to any authenticated caller; the underlying installer-distribution flow is itself obsolete
POST /resources/publish post-cycle-1 (AZ-183 reverted) same revert as /get-update — the publish counterpart of the OTA flow
POST /resources/get/{dataFolder?} cycle 2 (2026-05-14) obsolete — per-user encrypted-download flow no longer used by any client; ADR-003 retired
GET /resources/get-installer cycle 2 (2026-05-14) obsolete — installer-shipping era is over (browser SaaS + fTPM Jetsons)
GET /resources/get-installer/stage cycle 2 (2026-05-14) same as /resources/get-installer

Internal Logic

DI Registration

  • IUserServiceUserService (Scoped)
  • IAuthServiceAuthService (Scoped)
  • IResourcesServiceResourcesService (Scoped)
  • IDetectionClassServiceDetectionClassService (Scoped) — added by AZ-513
  • IDbFactoryDbFactory (Singleton)
  • ICacheMemoryCache (Scoped)
  • LazyCache via AddLazyCache()
  • FluentValidation validators auto-discovered from RegisterUserValidator assembly (also picks up CreateDetectionClassRequest, UpdateDetectionClassRequest validators introduced in cycle 1)
  • BusinessExceptionHandler registered as exception handler

Middleware Pipeline

  1. Swagger (dev only)
  2. CORS (AdminCorsPolicy)
  3. Authentication (JWT Bearer)
  4. Authorization
  5. URL rewrite: root //swagger
  6. Exception handler

Authorization Policies

  • apiAdminPolicy: requires RoleEnum.ApiAdmin role

The apiUploaderPolicy (RoleEnum.ResourceUploader OR ApiAdmin) was added by AZ-183 and removed in the same cycle when the OTA endpoints it guarded were retired (see "Removed in cycle 1" above). RoleEnum.ResourceUploader itself remains as a data value (the seed uploader@azaion.com still uses it) but is no longer wired to any endpoint policy.

Configuration Sections

  • JwtConfig — JWT signing/validation
  • ConnectionStrings — DB connections
  • ResourcesConfig — file storage path (ResourcesFolder); the installer subfolders were dropped in cycle 2 along with the installer endpoints

Kestrel

  • Max request body size: 200 MB (for file uploads)

Logging

  • Serilog: console + rolling file (logs/log.txt)

CORS

  • Allowed origins: https://admin.azaion.com, http://admin.azaion.com
  • All methods and headers allowed
  • Credentials allowed

Dependencies

All services, configs, entities, and request types from Azaion.Common and Azaion.Services.

Consumers

None — this is the application entry point.

Data Models

None defined here.

Configuration

Reads JwtConfig, ConnectionStrings, ResourcesConfig from IConfiguration.

External Integrations

  • PostgreSQL (via DI-registered DbFactory)
  • Local filesystem (via ResourcesService)

Security

  • JWT Bearer authentication with full validation (issuer, audience, lifetime, signing key)
  • Role-based authorization policies
  • CORS restricted to admin.azaion.com
  • Request body limit of 200 MB
  • Antiforgery disabled for resource upload endpoint
  • Password sent via POST body (not URL)

Tests

None directly; tested indirectly through integration tests.