4 Commits

Author SHA1 Message Date
Zimin A.N. 7abff8f73f fix(security): CSO findings — non-root containers + .env gitignore + actuator hardening
Три прямых фикса по /cso security audit на v2.45.2:

## Finding #1 (HIGH): Backend containers run as root

ordinis-app / ordinis-read-api / ordinis-projection-writer Dockerfile'ы
запускали JVM от root (eclipse-temurin:21-jre default'но не задаёт USER).
Compromise через Spring CVE / Jackson deserialization → root-в-контейнере
= escalation surface на ноду через любой pod misconfig.

Добавлено: `RUN groupadd -r -g 10001 app && useradd -r -u 10001 -g app
-s /sbin/nologin app` + `USER app`. UID 10001 — outside system (0-999)
и distribution reserved (1000-9999). `--chown=app:app` на COPY чтобы
JVM могла прочитать jar.

ordinis-migrations (USER liquibase) и docs (nginx default) уже non-root.

## Finding #2 (HIGH): .env / .env.local not in .gitignore

`.gitignore` блокировал *.pem, *.key, .gstack/, .claude/ — но не .env.
Развработчик с realный dotenv для local dev мог случайно `git add .` и
закоммитить creds. Сейчас нет committed .env (verified) но защита нулевая.

Добавлено: `.env`, `.env.local`, `.env.*.local`, `*.env` + whitelist
`!.env.example`, `!.env.template`, `!.env.sample` для шаблонов.

Существующий tracked `ordinis-admin-ui/.env.example` остался tracked
(verified `git ls-files | grep .env.example`).

## Finding #3 (MEDIUM): Spring Actuator permitAll() — defense-in-depth gap

SecurityConfig had `requestMatchers("/actuator/**").permitAll()` →
любой pod в кластере мог `curl ordinis-app:8080/actuator/env` и
получить ORDINIS_KEYCLOAK_ADMIN_CLIENT_SECRET, DB creds и пр.

VERIFIED: nginx ingress на проде НЕ проксирует /actuator/* (SPA fallback
отдаёт index.html), так что не exposed на интернет. Но pod-to-pod в
кластере = открыто.

Defense in two layers:

1. SecurityConfig: split actuator routes —
     /actuator/health/**, /actuator/info, /actuator/prometheus → permitAll
     /actuator/**                                              → denyAll
   Probes/Prometheus scrape работают, остальное блок.

2. application.yml для всех трёх Spring apps: narrowed default exposure
   to "health,info,prometheus". Поддерживается env override
   MANAGEMENT_ENDPOINTS_WEB_EXPOSURE_INCLUDE для staging diagnostic
   (включить env/configprops/loggers только когда нужно дебажить
   autoconfig).

## Тесты

- mvn package — все 15 модулей SUCCESS
- ordinis-rest-api + ordinis-auth tests — SUCCESS

## Manual verify post-deploy

После пророллится v2.45.3:
- staging+prod liveness/readiness probes должны остаться зелёными
  (/actuator/health/{liveness,readiness} в permitAll list).
- Prometheus scrape /actuator/prometheus → 200.
- ssh pod && curl localhost:8080/actuator/env → должен вернуть
  401/403 (или 404 если endpoint вообще выключен через exposure).

## Откат

Если probes сломаются (маловероятно — health endpoints whitelisted) —
revert этого MR. Image rollback к v2.45.2 через helm.
2026-05-27 19:02:34 +03:00
Александр Зимин 9050e2427e feat(notifications): TODO 7 — draft decision toast + email + bell badge 2026-05-14 14:40:35 +00:00
Zimin A.N. c5b00ff623 refactor(auth): domain-specific role names (consistent convention)
User feedback: универсальный 'ordinis:approver' отступал от convention
'ordinis:<domain>:<action>'. Меняю на domain-specific:

WorkflowRoles constants:
- APPROVER → SCHEMA_REVIEWER ('ordinis:schema:reviewer')
- PUBLISHER → SCHEMA_PUBLISHER ('ordinis:schema:publisher')
- Новая RECORD_REVIEWER ('ordinis:record:reviewer')

Applied:
- SchemaDraftService.decide() → require SCHEMA_REVIEWER
- SchemaDraftService.publish() → require SCHEMA_PUBLISHER
- DraftService.approve() / .reject() → require RECORD_REVIEWER

Frontend usePermissions.ts:
- ROLE_APPROVER + ROLE_PUBLISHER → ROLE_SCHEMA_REVIEWER +
  ROLE_SCHEMA_PUBLISHER + ROLE_RECORD_REVIEWER
- Новый hook useCanReviewRecord() для record draft actions

Keycloak setup (updated):
- ordinis:schema:reviewer
- ordinis:schema:publisher
- ordinis:record:reviewer
(Composite role 'ordinis:admin' = all три + scope roles — для удобства.)
2026-05-13 12:44:23 +03:00
Zimin A.N. a28fd0b352 feat: Maven multimodule scaffolding for Ordinis MDM service
- 10 модулей (domain, validation, events-api, outbox, rest-api, app, read-api, projection-writer, cuod-bundle, migrations)
- Parent pom + BOM с Spring Boot 3.4.2, Spring Cloud 2024.0.0, Vault Config 4.2.0
- ordinis-app: Spring Boot main с Actuator/Prometheus/Logstash JSON encoder/OpenTelemetry/Cloud Config/Vault skeleton
- ordinis-migrations: Liquibase changelogs (dictionary_definitions/records, audit_log, outbox_events, idempotency_keys, EXCLUSION CONSTRAINT через btree_gist)
- Multi-stage Dockerfiles для app и migrations
2026-05-03 00:41:53 +03:00