docs+src: complete Steps 1-3 outcomes + auth re-sync baseline

This commit captures everything produced during autodev existing-code
Steps 1 (Document), 2 (Architecture Baseline Scan), and 3 (Test Spec),
together with the targeted auth + CORS re-sync triggered on 2026-05-14
when codebase drift was detected at Step 4 entry. None of this work was
previously committed.

Step 1 (Document) — 50+ _docs/02_document/ files: problem, solution,
architecture, system flows, glossary, module-layout, per-component
specs (01..06), modules, deployment, diagrams, data model, FINAL
report, verification log, discovery.

Step 2 (Architecture Baseline) — architecture_compliance_baseline.md.
Verdict PASS_WITH_WARNINGS (0 Critical, 0 High, 1 Medium, 2 Low). No
High/Critical findings; auto-chained to Step 3 per existing-code flow.

Step 3 (Test Spec) — _docs/02_document/tests/* (67 scenarios across
blackbox, security, resilience, resource-limit, performance), plus
e2e/docker-compose.test.yml, e2e/seed/run.sh, scripts/run-tests.sh,
scripts/run-performance-tests.sh. Coverage 88% over the active scope
(40 of 45 items covered, 6 RB-deferred, 5 documented-as-uncovered).

Targeted auth + CORS re-sync — replaces the deleted in-house token
issuer with a JWKS-verifier model. AuthController and TokenService
removed; JwtExtensions switched from HS256 symmetric to ES256 over
admin's JWKS. ConfigurationResolver and CorsConfigurationValidator
added under src/Infrastructure/. ADR-002 and ADR-006 retired; SEC-01,
SEC-02, SEC-03 marked Closed. One new testability risk recorded in
architecture.md Open Risks Section 6 (JWKS HTTPS gating).

Source changes:
- src/Auth/JwtExtensions.cs (modified) — ES256, JWKS, alg pinning
- src/Program.cs (modified) — DI wiring for ConfigurationResolver
  and CorsConfigurationValidator
- src/Controllers/AuthController.cs (deleted) — no in-service issuance
- src/Services/TokenService.cs (deleted) — same
- src/Infrastructure/ConfigurationResolver.cs (new)
- src/Infrastructure/CorsConfigurationValidator.cs (new)
- .env.example (new) — required env var documentation
- .gitignore (updated)

Cross-repo coordination: _docs/cross-repo/flights_h1_h2_h3_change_spec
captures the change-spec for downstream services that consumed the now
deleted /auth endpoints.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Oleksandr Bezdieniezhnykh
2026-05-14 20:19:05 +03:00
parent 08eadc1158
commit 03f879206e
66 changed files with 6006 additions and 133 deletions
+135
View File
@@ -0,0 +1,135 @@
# E2E test stack for Azaion.Annotations.
# Documented in _docs/02_document/tests/environment.md.
# Invoked by scripts/run-tests.sh (functional) and scripts/run-performance-tests.sh (perf).
services:
postgres:
image: postgres:13
environment:
POSTGRES_DB: annotations
POSTGRES_USER: annotations
POSTGRES_PASSWORD: annotations
volumes:
- pg-data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U annotations -d annotations"]
interval: 2s
timeout: 3s
retries: 30
rabbitmq:
image: rabbitmq:3.13-management
environment:
RABBITMQ_DEFAULT_USER: annotations
RABBITMQ_DEFAULT_PASS: annotations
# Enable the streams plugin (required by FailsafeProducer / RabbitMQ.Stream.Client).
command: >
bash -c "rabbitmq-plugins enable --offline rabbitmq_stream rabbitmq_management
&& exec docker-entrypoint.sh rabbitmq-server"
healthcheck:
test: ["CMD", "rabbitmq-diagnostics", "ping"]
interval: 5s
timeout: 5s
retries: 30
# Mock JWKS issuer. Generates a fresh ES256 key pair on first start, writes the
# private key under /keys (consumed by e2e-runner to mint per-test tokens) and
# serves the matching public JWKS at http://e2e-issuer:8080/.well-known/jwks.json.
# The annotations service trusts this JWKS endpoint at boot.
e2e-issuer:
image: python:3.12-alpine
volumes:
- ../tests/harness:/harness:ro
- jwt-keys:/keys
command: ["python", "/harness/mock_issuer.py"]
healthcheck:
test: ["CMD", "wget", "-qO-", "http://localhost:8080/.well-known/jwks.json"]
interval: 2s
timeout: 3s
retries: 30
annotations:
build:
context: ..
dockerfile: src/Dockerfile
args:
AZAION_REVISION: test-${GIT_SHA:-local}
environment:
# E2ETest relaxes the JWKS HTTPS-only constraint; never used in production builds.
ASPNETCORE_ENVIRONMENT: E2ETest
DATABASE_URL: postgresql://annotations:annotations@postgres:5432/annotations
JWT_ISSUER: https://e2e-issuer.test
JWT_AUDIENCE: annotations-e2e
JWT_JWKS_URL: http://e2e-issuer:8080/.well-known/jwks.json
CorsConfig__AllowedOrigins__0: http://e2e-runner.test
RABBITMQ_HOST: rabbitmq
RABBITMQ_STREAM_PORT: "5552"
RABBITMQ_PRODUCER_USER: annotations
RABBITMQ_PRODUCER_PASS: annotations
AZAION_REVISION: test-${GIT_SHA:-local}
volumes:
- annotations-images:/data/images
- annotations-videos:/data/videos
- annotations-deleted:/data/deleted
- ../../detections/_docs/00_problem/input_data:/fixtures:ro
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
e2e-issuer:
condition: service_healthy
healthcheck:
test: ["CMD-SHELL", "wget -qO- http://localhost:8080/health >/dev/null || exit 1"]
interval: 3s
timeout: 3s
retries: 30
dataseed:
image: postgres:13
depends_on:
annotations:
condition: service_healthy
volumes:
- ./seed:/seed:ro
entrypoint: ["/bin/sh", "/seed/run.sh"]
environment:
ANNOTATIONS_BASE_URL: http://annotations:8080
DATABASE_URL_PSQL: postgres://annotations:annotations@postgres:5432/annotations
e2e-runner:
build:
context: ..
dockerfile: tests/Azaion.Annotations.E2E/Dockerfile
depends_on:
dataseed:
condition: service_completed_successfully
environment:
ANNOTATIONS_BASE_URL: http://annotations:8080
JWT_ISSUER: https://e2e-issuer.test
JWT_AUDIENCE: annotations-e2e
RABBITMQ_HOST: rabbitmq
RABBITMQ_STREAM_PORT: "5552"
RABBITMQ_USER: annotations
RABBITMQ_PASS: annotations
FIXTURES_DIR: /fixtures
# Test profile: "functional" (default) or "performance".
E2E_RUN_PROFILE: ${E2E_RUN_PROFILE:-functional}
# Direct DB access for blackbox-allowed assertions (outbox row counts, etc.).
DATABASE_URL_PSQL: postgres://annotations:annotations@postgres:5432/annotations
volumes:
- ../../detections/_docs/00_problem/input_data:/fixtures:ro
- ./e2e-results:/results
# Mount the mock issuer's private key (read-only) so the runner can mint per-test ES256 tokens.
- jwt-keys:/keys:ro
volumes:
pg-data: {}
annotations-images: {}
annotations-videos: {}
annotations-deleted: {}
jwt-keys: {}
networks:
default:
name: e2e-net
+27
View File
@@ -0,0 +1,27 @@
#!/bin/sh
# E2E dataseed: nothing to seed at the auth layer because annotations is
# verifier-only and has no users table. Tokens are minted on demand by the
# e2e-runner using the mock-issuer's private key (see _docs/02_document/tests/
# test-data.md → "Bearer token harness").
#
# This script is kept as a placeholder so e2e-runner's depends_on chain
# (dataseed: service_completed_successfully) still has a clear ordering
# anchor between annotations boot and test execution. Add table-level seed
# inserts here if a future test class needs reference rows beyond what the
# migrator already seeds.
set -eu
echo "[seed] waiting for /health"
i=0
while ! wget -qO- "$ANNOTATIONS_BASE_URL/health" >/dev/null 2>&1; do
i=$((i+1))
if [ "$i" -ge 60 ]; then
echo "[seed] /health did not return 200 after 60 attempts" >&2
exit 1
fi
sleep 1
done
echo "[seed] /health is up; nothing to seed (verifier-only auth, no users table)"
echo "[seed] done"