You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
BLOCKER fixes from the Google production-readiness review:
B3 (SSRF): Dropped fc/fd ULA prefixes from host_is_storage_safe.
AWS IMDSv2 at fd00:ec2::254 passed the storage allowlist — a
compromised control plane could exfiltrate the full database to the
cloud instance-metadata service.
B4 (SSRF/RCE): Disabled CURLOPT_FOLLOWLOCATION in hydration. The SSRF
guard only inspects the initial URL host; a 302 to 169.254.169.254
bypassed it and fed attacker-controlled bytes into the SQL executor
(full RCE chain). Presigned S3 GETs never 302, so zero benign impact.
H1 (silent data loss — CRITICAL): Async startup validation now clears
backup_enabled on failure. Without this, a wrong/revoked key kept
shipping rows to a dead CP → 401 → backoff → after max_attempts
(default 100) every row dead-lettered AND deleted from _pending_backup
→ is_healthy() flipped GREEN (queue empty) = silent total data loss.
Now: backup_enabled=0 keeps capture queuing with attempts=0 (nothing
dead-letters), and a 60s periodic re-validation in the flush thread
re-enables the moment the control plane returns.
H6 (PII): Dead-letter log no longer dumps the raw payload SQL (which
contains customer row data like emails/names). Logs the payload id +
reason only; operator inspects _dead_backup via the DLQ tool.
H5 (README): Fixed ARKILIAN_DATABASE_TOKEN → ARKILIAN_API_KEY (the
real env var the C core reads). C users following the README were
setting the wrong variable and getting backup silently disabled.
H7 (hardened build): Added -fstack-protector-strong and
-D_FORTIFY_SOURCE=2 (Release builds) to CMakeLists. Standard
production hardening for cloud-hosted C binaries.
Also: filtered storage credentials fetches from control plane via
new GET /v1/storage/credentials endpoint (server/main.go). Client
signs SigV4 PUT URLs locally with cached creds — no per-upload
control-plane round trip. Ark HMAC-SHA256 primitives added to sha256.c.
Copy file name to clipboardExpand all lines: README.md
+6-6Lines changed: 6 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -64,7 +64,7 @@ default to empty; nothing phones home unless explicitly configured.
64
64
|`ARKILIAN_BACKUP_INTERVAL`|`3600`| Hourly snapshot interval in seconds (min 1) |
65
65
|`ARKILIAN_WAL_PUSH_URL`| (none) | Realtime destination for row changes — every write is shipped here as replayable SQL (e.g. control plane `POST /v1/wal/push`) |
66
66
|`ARKILIAN_SIGNED_URL_ENDPOINT`| (none) | Signed-URL issuer for hourly snapshot uploads (e.g. control plane `POST /v1/upload/request`). Independent of `ARKILIAN_WAL_PUSH_URL` — they are different endpoints |
67
-
|`ARKILIAN_DATABASE_TOKEN`| (none) | Bearer token sent with both endpoints (never attached to pre-signed storage URLs) |
67
+
|`ARKILIAN_API_KEY`| (none) | Bearer token sent with both endpoints (never attached to pre-signed storage URLs) |
68
68
|`ARKILIAN_ENABLE_BACKUP`|`1`|`0`/`false` disables outbound backup at startup; can be toggled at runtime with `db_backup_set_enabled()`|
69
69
|`ARKILIAN_MAX_QUEUE_DEPTH`|`100000`| Soft ceiling on `_pending_backup` rows. Once the queue reaches this depth the capture triggers pause INSERTs into the outbox (the application's own writes are unaffected, per the spec §0 "backup must never break the application" rule), and `db_backup_is_healthy()` flips to 0 so the loss of capture is visible via monitoring. Shipping drains the queue and capture resumes automatically when the depth drops back below the cap |
70
70
|`ARKILIAN_ALLOW_INSECURE`|`0`| Opt-in for cleartext `http://` endpoints that are NOT loopback / RFC1918 (e.g. an internal-but-public corporate aggregator). Default `0`: a non-HTTPS non-local endpoint is refused at startup and backup is disabled, so a misconfiguration cannot leak the bearer token in cleartext. Loopback (`127.x`, `::1`, `localhost`) and RFC1918 / link-local / ULA addresses are always permitted for dev without opt-in |
Configure the background worker with your `ARKILIAN_DATABASE_TOKEN` and endpoints obtained from [arkilian.com](https://arkilian.com) to stream raw row operations in real time.
243
+
Configure the background worker with your `ARKILIAN_API_KEY` and endpoints obtained from [arkilian.com](https://arkilian.com) to stream raw row operations in real time.
244
244
245
245
```js
246
246
importArkilianfrom'arkilian';
247
247
248
248
// Get your configuration and API token from https://arkilian.com
249
-
consttoken=process.env.ARKILIAN_DATABASE_TOKEN;
249
+
consttoken=process.env.ARKILIAN_API_KEY;
250
250
constdb=newArkilian(token, 'app.sqlite');
251
251
252
252
db.exec(`CREATE TABLE IF NOT EXISTS users (
@@ -308,7 +308,7 @@ Manage backups dynamically without restarting the application process.
308
308
importArkilianfrom'arkilian';
309
309
310
310
// Retrieve your API token from https://arkilian.com
0 commit comments