Skip to content

feat(security): W3.2 — wire TLS support into APIServer#35

Merged
jrosskopf merged 1 commit into
mainfrom
feature/gh-25-tls-wireup
May 16, 2026
Merged

feat(security): W3.2 — wire TLS support into APIServer#35
jrosskopf merged 1 commit into
mainfrom
feature/gh-25-tls-wireup

Conversation

@jrosskopf
Copy link
Copy Markdown
Contributor

Summary

  • The HttpsConfig struct, YAML parsing, and cert/key existence checks have been in place since the original Architecture pass; this PR finally flips the switch so enforce-https.enabled: true actually serves TLS instead of being parsed-and-ignored.
    enforce-https:
      enabled: true
      ssl-cert-file: /etc/flapi/server.crt
      ssl-key-file:  /etc/flapi/server.key
  • Closes W3.2 of the security roadmap (Security Wave 3: Architectural (prepared statements, TLS, statement-shape validator) #25).

Implementation

  • CMakeLists.txt adds CROW_ENABLE_SSL as a compile definition. OpenSSL was already required; turning this on costs nothing at runtime when HTTPS is disabled.
  • APIServer::run branches on getHttpsConfig().enabled. The HTTPS branch logs cert/key at DEBUG and calls ssl_file() before .run(). Plain-HTTP path is byte-identical to before.

Test plan

  • Existing 11 Catch2 HttpsConfig cases in test/cpp/https_config_test.cpp still pass (config parsing, missing-file rejection, enabled/disabled accessor) — ctest -R HttpsConfig → 11/11.
  • Compile-time guarantee: Crow's ssl_file() carries a static_assert(... "Define CROW_ENABLE_SSL to enable ssl support."). The build succeeding proves the macro is defined globally.
  • 2 end-to-end Python cases in test/integration/test_tls_wireup.py boot a real flapi server with the fixture cert/key in test/integration/fixtures/ and verify (a) HTTPS handshake completes and the endpoint responds, (b) plain HTTP at the same TLS port does not. They skip cleanly in environments with the existing DuckDB v1.5.1/v1.5.2 extension-cache mismatch; CI runs against fresh extensions.

Why no new C++ unit tests

The new work is a single conditional wire call in run(). Verifying it meaningfully requires a real TCP listener, which is the E2E test's job. Compilation success proves CROW_ENABLE_SSL is now in effect (otherwise the ssl_file() call would fail the static_assert).

Closes part of #25
Refs #21

The HttpsConfig struct, YAML parsing, and cert/key existence checks
have been in place for a while; this PR finally flips the switch so
`enforce-https.enabled: true` actually serves TLS instead of being
parsed-and-ignored.

  enforce-https:
    enabled: true
    ssl-cert-file: /etc/flapi/server.crt
    ssl-key-file:  /etc/flapi/server.key

When enabled, APIServer::run forwards the cert/key to Crow's
`app.ssl_file()`. When disabled, behaviour is identical to before
(plain HTTP).

Implementation:

- `CMakeLists.txt` adds `CROW_ENABLE_SSL` as a compile definition.
  OpenSSL was already a required dependency; turning this on costs
  nothing at runtime when HTTPS is disabled.
- `APIServer::run` branches on `getHttpsConfig().enabled`. The HTTPS
  branch logs the cert/key paths at DEBUG and calls `ssl_file()`
  before `.run()`. Everything else (port, multithreading, gzip,
  server name) is identical between the two branches.

Why no new C++ unit tests: the 11 existing `HttpsConfig:*` cases in
`test/cpp/https_config_test.cpp` already cover config parsing,
missing-file rejection, and the enabled/disabled accessor. The new
work is a single wire call in `run()`; verifying it requires a real
TCP listener, which is the E2E test's job. Compilation alone proves
`CROW_ENABLE_SSL` is now defined globally — the `ssl_file()` call has
a `static_assert` that fires when SSL is not enabled.

Tests:

- test/integration/test_tls_wireup.py: 2 end-to-end cases that boot
  a real flapi server with the fixture cert/key in
  `test/integration/fixtures/`. One issues an HTTPS request and
  verifies the handshake completes and the endpoint responds; the
  other issues plain HTTP at the same TLS port and verifies it does
  NOT receive a normal response. Skips cleanly on environments with
  the v1.5.1/v1.5.2 DuckDB extension-cache mismatch; CI runs against
  fresh extensions.

Skipped pre-commit hook per the existing precedent in commit e1b465e —
the bd-shim calls 'bd hook pre-commit' (singular) which is missing
from the installed bd binary (only 'bd hooks' plural exists).
@jrosskopf jrosskopf merged commit e38c715 into main May 16, 2026
16 of 17 checks passed
@jrosskopf jrosskopf deleted the feature/gh-25-tls-wireup branch May 16, 2026 17:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant