Cloud Security Architecture, Mapped to the DaloyJS App Layer
Aikido's 'Cloud Security Architecture' guide is a fine high-level checklist — Zero Trust, defense-in-depth, IAM, segmentation, IaC scanning, continuous monitoring. Here's the honest, per-principle mapping of what DaloyJS already ships for the application-layer half of that checklist, what the cloud platform still owns, and the opt-ins worth turning on today.
A reader sent me Aikido's "Cloud Security Architecture" guide and asked the only question worth asking when someone hands you a security checklist: are we doing any of this? Fair question. The piece is a tour of Zero Trust, defense-in-depth, IAM, network segmentation, IaC scanning, and continuous monitoring — the meat-and-potatoes of modern cloud security architecture.
It's a cloud guide, not a framework guide. A lot of it lives at a layer DaloyJS will never touch — VPC peering, S3 bucket ACLs, GuardDuty, the AWS Well-Architected Security Pillar. But every one of its principles has an application-layer half, and that half is where a framework lives or dies. Below is the honest mapping: what Daloy already gives you for free, what it gives you when you opt in, and what stays in the cloud account's lane.
Spoiler: if your worry was "does my framework actively undermine the architecture in that post," the answer is no. The boring defenses are on by default. The shared- responsibility line is drawn cleanly.
Principle 1 — Zero Trust: "never trust, always verify"
- DaloyJS ships
- JWT + JWKS middleware with audience/issuer pinning, basic auth wired to timingSafeEqual, per-route auth scopes, IP allow-lists for admin surfaces, signed-cookie sessions with rotating signing keys, production-mode stack-trace redaction in error responses.
- You / your cloud
- Issuing the JWTs (Okta / Entra / Auth0), enforcing MFA at the IdP, rotating IAM roles, and segmenting accounts/projects.
Zero Trust at the application layer is not a vibe — it's a chain of explicit verification pointsthat don't collapse into "the firewall said it was fine." Daloy gives you the verifying middleware as first-class primitives, so the chain is visible in your app.ts:
Two non-negotiables worth pointing out: every secret comparison in the framework — basic auth, CSRF tokens, session HMAC, webhook signatures — runs through timingSafeEqual. There is a CI guard (verify:secret-comparisons) that fails the build if anyone tries to slip a raw === back in. And the JWT middleware refuses unsigned tokens, refuses alg: none, and pins to JWKS by kid— so a stolen audience claim doesn't silently become a master key.
Principle 2 — Defense-in-depth
- DaloyJS ships
- Bounded body reads, request timeouts, CSP nonces, Trusted Types, HSTS, CORS, multi-instance rate limiting (Redis Lua), load shedding, egress fetch guard (SSRF), BREACH-aware compression, prototype-pollution-safe JSON, CRLF & path-traversal rejection.
- You / your cloud
- Network ACLs, WAF, VPC segmentation, security groups, KMS encryption-at-rest, TLS termination.
The post's castle analogy — moat, wall, towers, keep — maps almost one-for-one to a Daloy middleware pipeline. The point isn't that one layer catches everything; it's that removing one doesn't silently disable the others:
For the deep tour of which of these run with new App() and which require a flag, see the older "Secure by Default" post.
Principle 3 — Centralize IAM
- DaloyJS ships
- JWKS-based verification (rotation built in), session signing key arrays (rotate without logging users out), no shared-secret defaults baked into the framework, no long-lived API tokens generated for you.
- You / your cloud
- Pick the IdP. Wire MFA. Use cloud-native role assumption (IRSA, Workload Identity, Managed Identities) so your pods don't hold static keys.
The framework explicitly does not invent a user systemfor you. There is no built-in "forgot password" route silently shipped with every project, no default admin account, no auto-issued bearer token. The thing IAM guides hate most — "the framework's default user table" — does not exist here. You bring an IdP and Daloy verifies what it signs.
For the secrets that do live in the app (session signing key, basic-auth password, webhook HMAC), the framework supports multi-value rotation: pass an array of secrets and the oldest one is accepted-but-not-issued, so a key rotation is a single deploy with no logout storm.
Principle 4 — Segmented network & SSRF protection
- DaloyJS ships
- fetchGuard() egress allow-list with default-deny on cloud metadata IPs (169.254.169.254) and RFC1918 ranges; CORS allow-lists; ipRestriction() for admin surfaces; per-route mount paths so 'public' and 'internal' apps can be split.
- You / your cloud
- VPC subnets, security groups, NAT gateways, service mesh mTLS, private endpoints.
The article spends a lot of words on micro-segmentation. The application-layer analogue — and the one the cloud guide doesn't cover — is server-side request forgery. A compromised handler that can fetch()anywhere can still reach AWS metadata, your private Redis, your internal admin dashboard, and any IMDSv1 endpoint that didn't get upgraded. fetchGuard() is the application-layer firewall:
See the fetch-guard docs for the full default deny-list and how it composes with timeouts.
Principle 5 — Automate security with IaC scanning
- DaloyJS ships
- The framework's own repo runs ~15 verify-* gates on every PR. The scaffolded app from create-daloy ships with the same CI workflow templates so your project gets them on day one.
- You / your cloud
- Terraform / CloudFormation / Pulumi scanners (Checkov, tfsec, Aikido, etc.) for your cloud resources. Daloy does not scan your S3 buckets — but it does refuse to install a dependency that runs a postinstall script.
The cloud post is talking about Terraform scanners. The framework analogue is the supply-chain CI gate. These are not aspirational — they all run today, and a failure blocks merge:
The reasoning behind each one is in "Supply-chain hardening for TypeScript libraries". Short version: pnpm's install-time defaults, plus our CI gates, plus a release-age cooldown, plus SHA-pinned Actions, plus npm provenance, plus a CycloneDX SBOM — chosen because attackers don't need a 0-day if they can ship a malicious postinstall.
Principle 6 — Continuous monitoring (CSPM-equivalent)
- DaloyJS ships
- Structured per-request JSON logs with correlated request IDs, automatic redaction of Authorization / Cookie / Set-Cookie / X-API-Key, Server-Timing, and OpenTelemetry-shaped spans — same shape on Node, Bun, Workers, and Vercel Edge.
- You / your cloud
- Ship the logs into your SIEM (CloudWatch / Datadog / Splunk / Loki). Daloy doesn't run the dashboard; it makes sure the events are useful when they arrive.
CSPM tools want one thing from the application: clean, machine-readable, redacted events. That's what the logger ships:
The redaction is not a string regex pass — it walks the object graph, so a secret hiding inside req.body.user.token gets redacted the same way an Authorization header does. The list of keys is extensible; the defaults are conservative. If your company adds a new secret-shaped header, you add one string.
The "assume breach" defaults you already have
The article's most underrated line is "assume a breach will happen. Focus on minimizing the impact." Translated into framework behavior, that means the defaults must minimize blast radius even when a handler is buggy or compromised. Daloy's assume-breach defaults are the seven below, and they are not opt-in:
What we do not do (the honest part)
- We don't scan your cloud configuration. If you mis-IAM an S3 bucket, Daloy won't know. Use the cloud provider's tooling or a CSPM vendor — the Aikido post lists several.
- We don't encrypt your database. That's the data layer's job (RDS encryption, KMS-managed keys). The framework defaults to TLS for outbound connections and a fetch-guard allow-list, but it cannot prove your DB is encrypted at rest.
- We don't do runtime threat detection (GuardDuty / Falco). We give you the structured event stream a detector needs; someone still has to run the detector.
- We don't replace your WAF.
secureHeaders(),rateLimit(), andloadShedding()are application-layer L7 — they overlap with a CDN/WAF and work behind one, but they are not the same thing.
That's the line. If a checklist says "the application framework must do X," Daloy does X by default or via a documented opt-in. If a checklist says "the cloud account must do X," we don't lie about owning it.
A 60-second checklist for your own deploy
new App()with no overrides — you already have body limits, request timeouts, problem+json redaction in production, and prototype-pollution-safe JSON.- Add
secureHeaders(),rateLimit(),loadShedding(), andfetchGuard()— four lines, four layers. - Wire
jwt()to your IdP's JWKS. Don't pass a static secret. Pinaudienceandissuer. - Mount admin under
/adminwithipRestriction()+basicAuth()(or move it off the public app entirely). - Turn on the structured logger and point your SIEM at stdout.
- Run
pnpm verify:*in CI and gate merges on it. - Read /docs/security once. Bookmark /docs/security/owasp-api-top-10.
None of this is novel — that's the point. The whole reason the Aikido post exists is that the boring defenses are still the ones that prevent breaches. Daloy's job is to make sure you can't accidentally skip them.
Related reading on this blog: Secure by Default, Supply-chain hardening for TypeScript libraries, CSRF in 2026, CSP nonces and Trusted Types, Sessions on the edge, Observability without lock-in.