build log: feb 23 — securing the gateway

2026-02-23

this build log is automatically generated

session stats
2.9k tool calls 140 files 51 sessions
tool breakdown
Read
961
Bash
840
Edit
361
Grep
193
Glob
159
Write
91
TaskUpdate
88
Task
60
TaskCreate
45
WebFetch
34
WebSearch
21
TaskOutput
12
ExitPlanMode
10
NotebookEdit
10
EnterPlanMode
8
AskUserQuestion
6
TaskStop
2

what i shipped today

i shipped a complete overhaul of secret management and token encryption for the tenant gateway. this involved integrating google cloud secret manager for admin secrets and kms envelope encryption for per-user oauth tokens. a big step towards better security.

auth0 scopes and gemini api rate limits… oh my

spent way too long this morning debugging the apprentice chat. turns out my auth0 scopes were wrong. then, after fixing that, i immediately hit a gemini api rate limit. felt like whack-a-mole.

secret manager: goodbye plaintext secrets

i spent the bulk of the day implementing google cloud secret manager. the goal was to eliminate plaintext secrets. i built a new secrets.ts module with functions for saving, retrieving, and deleting secrets. each secret id follows the convention gs-{tenantId}-{category}-{key}. i also added a 5-minute in-memory cache to avoid excessive api calls.

kms envelope encryption: securing oauth tokens

next up was kms envelope encryption for per-user oauth tokens. this was a bit more involved. i created a crypto.ts module with functions for encrypting and decrypting tokens using aes-256-gcm. each tenant gets its own data encryption key (dek), wrapped by kms and cached for 10 minutes. backward compatibility was key — the system checks for both encrypted and plaintext formats.

admin secrets api: managing secrets via the gateway

to manage the secrets, i created a new admin api (admin/secrets.ts). this api, secured with firebase id token auth and role checks, allows posting and deleting secrets. the api handles different categories of secrets (connector, custom, llm, etc.), each with specific firestore metadata paths.

lazy initialization and in-memory caching

one key pattern i used was lazy initialization for gcp clients. this avoids credential checks in test environments. also implemented in-memory caching with ttl for both secret manager and the data encryption key (dek). same pattern as engineCache in mcp.ts.

apprentice gets an llm

finally, i hooked up the “apprentice” llm by configuring the llm provider for the apprentice tenant. it’s using forward_bearer mode with injectLlmProviderKeys: true. this simplifies the configuration and makes it more secure.


david crowe — reducibl.com


interested in working together? let's talk

← back to build logs