# 1C bridge security rollout — 2026-10-20 Applied to the bridge only. API and PostgreSQL must not be rebuilt or restarted. ## Implemented - BSL string quote escaping and control-character removal; phone filtering. - UUID full-match validation, ISO date canonicalization and escaping. - X-Api-Key/Bearer authorization using the existing ONEC_API_KEY. - Request body limit of 64 KiB; MCP/DB secrets supplied through environment. - Compose bridge: UID 10001, fixed IP 172.20.0.50, read-only root filesystem, cap_drop ALL, no-new-privileges, tmpfs, no published host port. - Existing dana-medical_default network is external to Compose: prevents recreation of the live API/DB network. Existing subnet: 172.20.0.0/16. - Runtime Python file owned by UID10001 regardless of build-context permissions. - 19 supplied smoke assertions and 6 additional isolated security regressions. ## Host firewall: prepared, not installed Neither available SSH account (kadir or mikail) has sudo permission. Root SSH with the available keys is rejected. Therefore no host iptables rules or systemd units have been installed by this deployment. From the provider's root console, run: ```sh sh /home/mikail/dana-medical/deploy/install-1c-egress.sh ``` Then verify: ```sh python3 /home/mikail/dana-medical/deploy/verify-1c-egress.py ``` The unit includes PartOf=docker.service and is wanted by docker.service as well as multi-user.target, to reapply the rules on Docker restarts and host reboots. No actual Docker restart or host reboot was performed for testing. ## Upstream blocker During post-deployment checks, 10.240.70.70:6003 refused TCP connections. Authenticated /branches therefore returns 502 until the 1C MCP listener is available. A complete rollout requires /branches=200, a successful 1C sync cycle, and the firewall probes above. Security checks that fail before 1C are isolated from this upstream availability issue. No live test appointments were created. API logs before bridge replacement also contain connection-refused sync errors. Direct probes from the VPS host and API container confirm ECONNREFUSED (111). ## Public domain check At verification, danamedical.ru resolved to 92.53.96.37 (Timeweb/Bitrix), where /api/v1/health returned 404. The DANA service on this VPS returned 200 both directly at 172.17.0.1:8082/api/v1/health and over Caddy HTTPS with danamedical.ru Host/SNI explicitly resolved to 127.0.0.1. DNS was not changed by this work. ## Rollback material Private backup: /home/mikail/dana-security-backup-20261020-_gv_ic_u Previous runtime snapshot image: dana-1c-bridge:before-security-20261020 The old image had already been removed from Docker before this work, so the running root filesystem was exported and imported as a rollback image. Its Python runtime and dependencies were checked without network access. The backup contains original source, .env, the removed waitcall.go.root-backup, and the old container configuration. Do not publish or commit the backup. No password/token rotation, API/DB hardening, Git history rewrite or unrelated deployment was performed. The original unrestricted bridge is intentionally not left running alongside the new bridge.