raindancers-cloudfront 0.0.3 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +67 -128
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,176 +1,115 @@
|
|
|
1
|
-
#
|
|
1
|
+
# The CDN Is Already a Zero Trust Gateway
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Many organisations are buying, evaluating, or already paying for zero trust network access (ZTNA) overlay products. These are tools that sit in front of your workloads, verify identity, enforce policy, and only then allow traffic through.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
I've implemented them into several environments, and it made me think about what they're really doing at the fundamental layer.
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Here's the thing — if you're running web applications behind a CDN, you already have that enforcement point.
|
|
8
8
|
|
|
9
|
-
##
|
|
9
|
+
## What Zero Trust Actually Means at the Edge
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
Zero trust, stripped of the marketing, means: don't trust the network. Verify every request. Enforce policy as close to the requester as possible.
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
- Windows 10/11 with WSL2 enabled
|
|
15
|
-
- Docker Desktop for Windows with WSL2 backend enabled
|
|
16
|
-
- VS Code with Remote Development extension pack installed
|
|
13
|
+
A CDN edge node is, by definition, the closest compute to the requester. Every major CDN provider now offers programmable compute at the edge — AWS CloudFront has CloudFront Functions and Lambda@Edge, Cloudflare has Workers, Azure has Azure Front Door with Rules Engine and Azure Functions integration.
|
|
17
14
|
|
|
18
|
-
|
|
15
|
+
That means you can verify identity, validate tokens, check session state, and enforce access policy *before a single byte reaches your origin infrastructure*. Not at the load balancer. Not at the API gateway. At the edge, milliseconds from the user.
|
|
19
16
|
|
|
20
|
-
|
|
17
|
+
That's zero trust enforcement. It's included in the price of your CDN.
|
|
21
18
|
|
|
22
|
-
|
|
23
|
-
```bash
|
|
24
|
-
cd ~
|
|
25
|
-
git clone <repository-url>
|
|
26
|
-
cd cdk-api
|
|
27
|
-
```
|
|
19
|
+
## The Architecture
|
|
28
20
|
|
|
29
|
-
|
|
30
|
-
```bash
|
|
31
|
-
code .
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
4. **Reopen in Container**: When prompted by VS Code, click "Reopen in Container"
|
|
35
|
-
- Or use Command Palette: `Dev Containers: Reopen in Container`
|
|
21
|
+
Let me walk through what this looks like on AWS CloudFront, since that's where I've built a working implementation. The same principles apply to Cloudflare and Azure Front Door.
|
|
36
22
|
|
|
37
|
-
|
|
23
|
+
```mermaid
|
|
24
|
+
sequenceDiagram
|
|
25
|
+
participant User
|
|
26
|
+
participant WAF
|
|
27
|
+
participant CF as CloudFront Function
|
|
28
|
+
participant KVS as KeyValueStore
|
|
29
|
+
participant Edge as Lambda@Edge
|
|
30
|
+
participant Origin
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
User->>WAF: Request
|
|
33
|
+
Note over WAF: Rate limiting<br/>Geo-blocking<br/>Bot detection<br/>IP reputation
|
|
40
34
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
```
|
|
35
|
+
WAF->>CF: Allowed request
|
|
36
|
+
CF->>KVS: Check session revocation
|
|
37
|
+
KVS-->>CF: Session status
|
|
45
38
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
Follow the prompts and select:
|
|
58
|
-
- **GitHub.com**
|
|
59
|
-
- **HTTPS** protocol
|
|
60
|
-
- **Login with a web browser** (device code flow)
|
|
61
|
-
- Copy the one-time code and press Enter to open the browser
|
|
62
|
-
- Paste the code in GitHub to complete authentication
|
|
63
|
-
|
|
64
|
-
**Note**: This installs `gh` in your WSL2 distro, not in the devcontainer. The devcontainer will inherit your WSL2 git credentials when cloning repositories.
|
|
65
|
-
|
|
66
|
-
### Verify Your Setup
|
|
39
|
+
alt Session valid
|
|
40
|
+
CF->>Origin: Forward request
|
|
41
|
+
Origin-->>User: Response
|
|
42
|
+
else Session invalid or missing
|
|
43
|
+
CF->>Edge: Auth required
|
|
44
|
+
Note over Edge: JWT validation<br/>OAuth token exchange<br/>Session establishment<br/>HMAC verification
|
|
45
|
+
Edge-->>User: Redirect to IdP / Set session cookie
|
|
46
|
+
end
|
|
47
|
+
```
|
|
67
48
|
|
|
68
|
-
|
|
49
|
+
The architecture uses layers, each doing what it's best at:
|
|
69
50
|
|
|
70
|
-
|
|
71
|
-
# Check filesystem type (should show ext4, not 9p)
|
|
72
|
-
df -h /workspaces/cdk-api
|
|
51
|
+
**CloudFront Functions** run on every request with sub-millisecond overhead. They handle the fast checks — is there a valid session cookie? Is the token format correct? Has this session been revoked? They can check revocation state against CloudFront KeyValueStore, which gives you a globally distributed, low-latency lookup table that's eventually consistent in seconds.
|
|
73
52
|
|
|
74
|
-
|
|
75
|
-
uname -a
|
|
76
|
-
```
|
|
53
|
+
**Lambda@Edge** handles the heavier work — full JWT validation, token exchange during OAuth callbacks, session establishment, HMAC signature verification. These run at regional edge caches, not every PoP, but they only fire on cache misses or specific request patterns like the auth callback.
|
|
77
54
|
|
|
78
|
-
**
|
|
55
|
+
**WAF** sits in front of the distribution and handles L7 filtering — rate limiting, geo-blocking, bot detection, IP reputation. This is your first line of defence before the request even reaches your CloudFront Function.
|
|
79
56
|
|
|
80
|
-
|
|
57
|
+
**KVS (KeyValueStore)** gives you real-time session revocation. When you need to kill a session — compromised credentials, user logout, policy change — you write to KVS and within seconds, every edge node worldwide will reject that session. No waiting for token expiry.
|
|
81
58
|
|
|
82
|
-
|
|
59
|
+
Together, these layers give you: identity verification, session management, real-time revocation, and L7 threat filtering. All at the edge. All before your origin sees a single request.
|
|
83
60
|
|
|
84
|
-
|
|
85
|
-
- Docker engine runs in WSL2
|
|
86
|
-
- Dev container runs in Docker with direct access to WSL2 filesystem
|
|
87
|
-
- Result: Native Linux I/O performance for operations like `npm install` and `yarn`
|
|
61
|
+
## Identity Provider Flexibility
|
|
88
62
|
|
|
89
|
-
|
|
63
|
+
This pattern is identity-provider agnostic. The edge functions validate JWTs — they don't care who issued them.
|
|
90
64
|
|
|
91
|
-
|
|
65
|
+
I've implemented this with two providers:
|
|
92
66
|
|
|
93
|
-
|
|
67
|
+
**Amazon Cognito** works well for B2C applications or when you want a fully managed user directory within AWS. Straightforward OAuth 2.0 / OIDC flows, user pools with MFA, and it integrates natively.
|
|
94
68
|
|
|
95
|
-
|
|
96
|
-
```bash
|
|
97
|
-
chmod +x .devcontainer/setup.sh .devcontainer/scripts/*.sh && .devcontainer/setup.sh
|
|
98
|
-
```
|
|
69
|
+
**Microsoft Entra ID (Azure AD)** is the enterprise play. If your organisation already uses Microsoft 365, your users already have identities in Entra ID. Federating CloudFront auth against Entra ID means single sign-on for your corporate web apps with no additional user directory to manage. This is a common pattern in enterprises running workloads on AWS but using Microsoft for identity.
|
|
99
70
|
|
|
100
|
-
|
|
101
|
-
1. Makes all shell scripts executable (`chmod +x`)
|
|
102
|
-
2. Runs the main setup script (`setup.sh`) only if the chmod succeeds (`&&`)
|
|
71
|
+
The edge functions handle the OAuth dance — authorization code flow, token exchange, session cookie creation — regardless of which provider issued the tokens.
|
|
103
72
|
|
|
104
|
-
##
|
|
73
|
+
## Where It Fits in Defence in Depth
|
|
105
74
|
|
|
106
|
-
|
|
107
|
-
- **TypeScript/Node.js 22**: Main development environment
|
|
108
|
-
- **AWS CLI**: Command line interface for AWS services
|
|
109
|
-
- **Docker-in-Docker**: Ability to run Docker containers within the devcontainer
|
|
110
|
-
- **Python**: Python runtime and tools
|
|
75
|
+
I'm not arguing this should be your *only* enforcement point in every case. Where it sits depends on what you're protecting.
|
|
111
76
|
|
|
112
|
-
|
|
113
|
-
- TypeScript language support
|
|
114
|
-
- AWS Toolkit for VS Code
|
|
115
|
-
- Amazon Q for VS Code
|
|
116
|
-
- GitHub Actions support
|
|
117
|
-
- JSON language support
|
|
118
|
-
- Python language support and linting
|
|
77
|
+
For a static single-page application or a content site with authenticated access, edge auth might be all you need. The origin is an S3 bucket. There's no application server to compromise. Enforcing auth at the edge and using Origin Access Control to lock the bucket down is a complete solution.
|
|
119
78
|
|
|
120
|
-
|
|
79
|
+
For applications with complex business logic, sensitive data, or regulatory requirements, edge auth is your *first* enforcement point. Your API layer still validates tokens, your backend still enforces authorisation, your database still has row-level security. But the edge layer means unauthenticated and revoked sessions never reach any of that infrastructure. It reduces your attack surface and your compute costs — why pay for your origin to reject requests that should never have arrived?
|
|
121
80
|
|
|
122
|
-
The
|
|
81
|
+
The choice is a spectrum, not a binary. In reality, this is likely a mixed model. Your ZTNA solution might still have a role — for legacy apps, thick client access, non-HTTP protocols, the things that don't flow through a CDN. That might be your IT team and a handful of power users. But if 90% of your workforce is accessing web applications through a browser, that's 90% of your ZTNA licensing you could potentially carve off.
|
|
123
82
|
|
|
83
|
+
That's not a rounding error. That's a material cost reduction.
|
|
124
84
|
|
|
125
|
-
|
|
126
|
-
- Runs `yarn install` to install project dependencies
|
|
85
|
+
## Web Apps — Yes. Legacy — It Depends.
|
|
127
86
|
|
|
128
|
-
|
|
129
|
-
- Creates AWS configuration directory
|
|
130
|
-
- Sets up AWS SSO profile configuration
|
|
131
|
-
- Configures default region (ap-southeast-2)
|
|
132
|
-
- **Note**: Contains placeholder values that need to be updated
|
|
87
|
+
This pattern works exceptionally well for modern web applications, which are a huge and growing part of the landscape. SPAs, server-rendered apps, static sites with authenticated APIs — anything that runs in a browser and speaks HTTP.
|
|
133
88
|
|
|
134
|
-
|
|
135
|
-
- Configures Model Context Protocol for Amazon Q
|
|
136
|
-
- Sets up filesystem, git, and AWS MCP servers
|
|
137
|
-
- Creates configuration in `~/.config/amazonq/mcp.json`
|
|
89
|
+
Where it gets harder is legacy applications. Apps that rely on server-side session state, non-standard authentication flows, thick client protocols, or anything that doesn't naturally sit behind a CDN. You can sometimes put a reverse proxy pattern in front of these, but you're fighting the architecture rather than working with it. For those workloads, traditional ZTNA tools or network-level controls may still be the right answer.
|
|
138
90
|
|
|
139
|
-
|
|
91
|
+
But be honest about the ratio. How much of your portfolio is web-based versus truly legacy? For most organisations, it's a significant majority.
|
|
140
92
|
|
|
141
|
-
|
|
142
|
-
- `setup.sh`: Main setup orchestrator
|
|
143
|
-
- `scripts/`: Individual setup scripts for different components
|
|
93
|
+
## You Don't Need Another Overlay
|
|
144
94
|
|
|
145
|
-
|
|
95
|
+
This is the point I really want to make. The major cloud providers and CDN vendors have given you programmable compute at the edge, global key-value stores, managed WAF, and native integration with identity providers. These are production-grade, globally distributed services that handle millions of requests per second.
|
|
146
96
|
|
|
147
|
-
|
|
148
|
-
- **Security**: Avoids running as root, following the principle of least privilege
|
|
149
|
-
- **Compatibility**: Pre-configured with proper permissions for Node.js development and NPM/Yarn package management
|
|
150
|
-
- **Standards**: Follows Node.js Docker image conventions and integrates well with VS Code devcontainers
|
|
151
|
-
- **Environment**: Provides a proper home directory (`/home/node`) for configuration files and shell access
|
|
97
|
+
You don't need to buy a separate zero trust product to sit in front of your web applications. You need to *configure the infrastructure you already have*.
|
|
152
98
|
|
|
99
|
+
There's a scaling argument here too. ZTNA overlay products funnel your traffic through resource-constrained nodes that you have to size, manage, and hope will scale when you need them to. CDNs are built to scale. That's their entire reason for existing. CloudFront operates across 600+ points of presence. You're not going to outgrow it.
|
|
153
100
|
|
|
154
|
-
|
|
101
|
+
The tools are there. CloudFront Functions, Lambda@Edge, WAF, KVS on AWS. Workers, KV, WAF on Cloudflare. Front Door, Rules Engine, Functions on Azure. The concept is the same — programmable edge compute enforcing identity and policy before traffic reaches your origin.
|
|
155
102
|
|
|
156
|
-
|
|
157
|
-
The Model Context Protocol (MCP) setup is not 100% configured correctly. Some manual configuration may be required after the devcontainer is created.
|
|
103
|
+
## Proof of Concept
|
|
158
104
|
|
|
159
|
-
|
|
160
|
-
The repository is configured for Git LFS but `git-lfs` is not installed in the devcontainer. You may see warnings about missing Git LFS. To resolve, either:
|
|
161
|
-
- Install Git LFS: `sudo apt-get update && sudo apt-get install git-lfs`
|
|
162
|
-
- Or remove Git LFS hooks if not needed: `rm .git/hooks/post-commit`
|
|
105
|
+
This repository ([`raindancers-cloudfront`](https://github.com/raindancers/raindancers-cloudfront)) is a CDK construct library published on npm that implements this pattern for AWS. It wires up CloudFront, Lambda@Edge, CloudFront Functions, WAF, KVS, and supports both Cognito and Entra ID authentication flows.
|
|
163
106
|
|
|
164
|
-
|
|
107
|
+
I want to be upfront — this is a proof of concept, not a battle-hardened production library. It needs more work, more testing, and more eyes on it. But it does enough to prove that the concept works end to end. You can stand up a CloudFront distribution with full OAuth 2.0 auth, session management, real-time revocation, and WAF protection using a handful of CDK constructs.
|
|
165
108
|
|
|
166
|
-
|
|
109
|
+
If the idea interests you, take a look, pull it apart, tell me what's broken. That's how it gets better.
|
|
167
110
|
|
|
168
|
-
##
|
|
111
|
+
## The Challenge
|
|
169
112
|
|
|
170
|
-
|
|
171
|
-
1. Edit the relevant script in the `scripts/` directory
|
|
172
|
-
2. Update AWS configuration in `aws-setup.sh` with your actual values
|
|
173
|
-
3. Modify NPM configuration in `npm-setup.sh` if using different registries
|
|
174
|
-
4. Rebuild the devcontainer to apply changes
|
|
113
|
+
Next time someone puts a ZTNA product evaluation on your desk, ask one question first: what can our CDN already do?
|
|
175
114
|
|
|
176
|
-
|
|
115
|
+
Imagine carving 90% off that licensing cost — and getting better scale in the process. That's worth an afternoon's investigation.
|