ASI Database Node API

Proposed public database connectivity — pending deployment review

The user explicitly requested database access from any public IP without a fixed client-IP allowlist. *.arybit.co.ke is not a source-network authentication policy; DNS suffix ownership does not establish a client's outbound address or identity. Individual database accounts and verified TLS enforce the direct interface trust boundary. HTTPS service credentials independently authorize application operations.

Read-only Azure account/tenant, NIC, NSG, effective-rule, effective-route and DNS inspection on 2026-10-16 found:

Proposed additional NSG rule, not applied:

Property Proposed value
Name allow-3306-public
Priority 200, observed unused; recheck immediately before execution
Source Internet service tag
Destination 10.30.1.4/32
Protocol / port TCP / 3306 only
Access / direction Allow / Inbound

Retain restricted SSH and the existing HTTP ACME/HTTPS rules. Do not add public SSH, database-admin UI, management listener, MySQL X protocol 33060, API worker port or arbitrary port ranges. No DNS or Azure configuration was changed. Private audit and proposal artifacts are in .state/dual-network-audit.json and .state/public-3306-proposal.json; they are deliberately excluded from Git/public UI.

Public 3306 exposes authentication and protocol surfaces to password guessing, connection exhaustion and engine vulnerabilities. Before opening it, install MySQL/MariaDB security updates; require_secure_transport and TLS-only consumer accounts; cap per-user/total connections; enable observed authentication-failure monitoring and an engine/platform-appropriate throttling/ban policy; verify backups; and keep all administration local/private. max_connect_errors limits handshake errors, not password brute force, and must not be presented as complete protection. Per-service HTTPS limits do not throttle direct MySQL authentication.

Prepare the listener plan using a mode-0600 copy of deploy-database-api/templates/direct-interface.env.example with the reviewed subscription/tenant and installed, valid certificate paths:

python deploy-database-api/ops/plan-mysql-interface.py --env-file /secure/direct-interface.env --output /secure/direct-plan

This validates the certificate/key, trust chain, SAN and remaining validity, then renders a TLS-only server configuration, a port-specific host-firewall script and an Azure network review plan. It never installs packages, changes Azure, enables a firewall, issues a certificate or restarts a service. The example opts into any IPv4 source specifically for 3306; it does not weaken SSH. A private bind address is appropriate because Azure maps the public IP to the NIC's private address.

After separate listener/account/host-firewall and backup acceptance, review this single proposed command against the selected subscription and current effective NIC/subnet rules. It is recorded here for review, not executed:

az network nsg rule create --subscription REVIEWED_SUBSCRIPTION --resource-group RG-ASI-DATABASE-NODE-API --nsg-name asi-database-node-api-v13-nsg --name allow-3306-public --priority 200 --direction Inbound --access Allow --protocol Tcp --source-address-prefixes Internet --source-port-ranges '*' --destination-address-prefixes 10.30.1.4/32 --destination-port-ranges 3306

Re-audit effective routes/security rules and test from an external network using a new TLS-only execute-only account. Verify valid credentials, wrong password, unknown user, plaintext rejection, chain/SAN/expiry failure and denied base-table/admin access. No external valid-user or public MySQL production acceptance was run. Undoing this rule closes direct public access without stopping HTTPS. Removing the rule alone does not undo account, schema, firewall or certificate changes.

Confirmed host state after SSH timeout

Pinned SSH timed out, but the same read-only inventory subsequently succeeded through Azure Run Command with the subscription/tenant reverified. Production's runtime configuration selects PostgreSQL; PostgreSQL is active, MySQL/MariaDB are inactive, and the successful host listener inventory contains no TCP 3306 listener. The VM-agent action ran only the bounded inventory script; no database, account, firewall, service or certificate configuration was changed. Its result is saved privately in .state/dual-host-audit.json.

Opening the proposed NSG rule alone cannot make the direct service functional. A reviewed MySQL/MariaDB installation, TLS/account/schema setup and authoritative data/consumer migration plan are required first. Preserve the active PostgreSQL service and existing data; do not switch the production runtime or reset schemas just to satisfy a health check. The SSH timeout remains an operational issue but does not prevent this read-only Azure-agent diagnosis.