refactor: remove obsolete resource download and installer endpoints
ci/woodpecker/push/01-test Pipeline failed
ci/woodpecker/push/02-build-push unknown status

- 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>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-14 04:17:55 +03:00
parent c7b297de83
commit 3a925b9b0f
60 changed files with 1202 additions and 982 deletions
@@ -1,16 +1,18 @@
# Authentication & Security
> **Cycle 1 (2026-05-13) note** — AZ-197 simplified `GetApiEncryptionKey` to `(email, password)` and removed `GetHWHash` outright. The hardware-binding threat model that motivated those primitives is no longer in scope (fTPM-anchored Jetsons + browser SaaS).
>
> **Cycle 2 (2026-05-14) note** — `GetApiEncryptionKey`, `EncryptTo`, and `DecryptTo` were all removed along with the encrypted-download endpoint. `Security` is now a one-method utility (`ToHash`) that backs SHA-384 password hashing.
## 1. High-Level Overview
**Purpose**: JWT token creation/validation and cryptographic utilities (password hashing, AES file encryption/decryption).
**Purpose**: JWT token creation/validation and password hashing (`Security.ToHash`).
**Architectural Pattern**: Service + static utility — `AuthService` is a DI-managed service for JWT operations; `Security` is a static class for cryptographic primitives.
**Architectural Pattern**: Service + static utility — `AuthService` is a DI-managed service for JWT operations; `Security` is a static class with a single SHA-384 helper.
**Upstream dependencies**: Data Layer (JwtConfig, IUserService for GetByEmail), ASP.NET Core (IHttpContextAccessor).
**Downstream consumers**: Admin API (token creation on login, current user resolution), User Management (password hashing for both web users and provisioned devices), Resource Management (encryption key derivation, stream encryption).
**Downstream consumers**: Admin API (token creation on login, current user resolution), User Management (password hashing for both web users and provisioned devices).
## 2. Internal Interfaces
@@ -26,11 +28,11 @@
| Method | Input | Output | Description |
|--------|-------|--------|-------------|
| `ToHash` | `string` | `string` (Base64) | SHA-384 hash |
| `GetApiEncryptionKey` | `string email, string password` | `string` (Base64) | Derives the per-user AES encryption key string. **Signature simplified by AZ-197** (`hardwareHash` parameter removed). |
| `EncryptTo` | `Stream input, Stream output, string key, CancellationToken` | void | AES-256-CBC encrypt stream |
| `DecryptTo` | `Stream encrypted, Stream output, string key, CancellationToken` | void | AES-256-CBC decrypt stream |
**Removed by AZ-197**: `GetHWHash(string hardware)` — no remaining callers in the post-cycle-1 codebase.
**Removed**:
- `GetHWHash(string hardware)` — removed by AZ-197 (cycle 1).
- `GetApiEncryptionKey(string email, string password)` — removed in cycle 2 (no remaining callers after `POST /resources/get/{dataFolder?}` was deleted).
- `EncryptTo` / `DecryptTo` extension methods — removed in cycle 2 (no remaining callers; the only consumer was `ResourcesService.GetEncryptedResource`, also deleted).
## 3. External API Specification
@@ -42,7 +44,7 @@ No direct database access. `AuthService.GetCurrentUser` delegates to `IUserServi
## 5. Implementation Details
**Algorithmic Complexity**: Encryption/decryption is O(n) where n is file size, streaming in 512 KB buffers.
**Algorithmic Complexity**: SHA-384 hashing is O(n) where n is input length; in practice it operates on short password strings only.
**State Management**: `AuthService` is stateless (reads claims from HTTP context per request). `Security` is purely static.
@@ -54,7 +56,6 @@ No direct database access. `AuthService.GetCurrentUser` delegates to `IUserServi
| Microsoft.AspNetCore.Authentication.JwtBearer | 10.0.3 | JWT middleware integration |
**Error Handling Strategy**:
- `EncryptTo` throws `ArgumentNullException` for unreadable streams or empty keys.
- JWT token creation does not throw (malformed config would cause runtime errors at middleware level).
- `GetCurrentUser` returns null if claims are missing or user not found.
@@ -65,15 +66,12 @@ None — `Security` itself is a utility consumed by other components.
## 7. Caveats & Edge Cases
**Known limitations**:
- Password hashing uses SHA-384 without per-user salt or key stretching. Not resistant to rainbow table attacks. (Unchanged by cycle 1.)
- The encryption-key salt is a hardcoded constant. (`Security.GetApiEncryptionKey` body — see `services_security.md`.)
- Password hashing uses SHA-384 without per-user salt or key stretching. Not resistant to rainbow table attacks. (Unchanged by cycles 1 and 2.)
- `GetCurrentUserEmail` assumes `ClaimTypes.Name` is always present; accessing a missing key would throw `KeyNotFoundException`.
- AES encryption prepends IV as first 16 bytes — consumers must know this format.
**Removed in cycle 1**: hardware fingerprint hashing was a known weakness (static salt, no rotation); deleting it via AZ-197 also removed that attack surface.
**Performance bottlenecks**:
- Large file encryption loads encrypted output into `MemoryStream` before sending — high memory usage for large files.
**Removed in cycle 2**: per-user file encryption (`GetApiEncryptionKey` + `EncryptTo` + `DecryptTo`). The hardcoded encryption-key salt and the in-memory `MemoryStream` round-trip are no longer attack / performance surfaces in this codebase.
## 8. Dependency Graph
@@ -81,7 +79,7 @@ None — `Security` itself is a utility consumed by other components.
**Can be implemented in parallel with**: User Management (shared dependency on Data Layer).
**Blocks**: Admin API, Resource Management (uses encryption).
**Blocks**: Admin API. (Resource Management no longer depends on this component after cycle 2 removed `EncryptTo` / `DecryptTo`.)
## 9. Logging Strategy