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
Copy file name to clipboardExpand all lines: README.md
+13-4Lines changed: 13 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -44,24 +44,33 @@ If you have isolated Kubernetes clusters, locked-down microservices, or a heavil
44
44
45
45
The default and recommended deployment is still the isolated single-server topology shown below: public URLs use `/{bucket}/{key}`, tickets publish to `AIR3_NATS_SUBJECT` (default `air3.tickets`), and only the Private Connector has S3 credentials or private S3 network access.
46
46
47
-
Multi-server mode is opt-in with `AIR3_MULTI_SERVER=true` on the Edge. In this mode, public URLs include a server alias: `/{server}/{bucket}/{key}`. The Edge verifies that the signed URL includes the same server alias, then publishes connector tickets to the routed NATS subject rendered from `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`). A connector for that alias sets `AIR3_SERVER_NAME=<server>` and subscribes to the same derived subject. For example, `server=blue` routes `/blue/demo-bucket/file.txt` to NATS subject `air3.blue` by default.
47
+
Multi-server mode is opt-in with `AIR3_MULTI_SERVER=true` on the Edge. In this mode, public URLs normally include a server alias and bucket: `/{server}/{bucket}/{key}`. The Edge verifies that the signed URL includes the same server alias, then publishes connector tickets to the routed NATS subject rendered from `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`). A connector for that alias sets `AIR3_SERVER_NAME=<server>` and subscribes to the same derived subject. For example, `server=blue` routes `/blue/demo-bucket/file.txt` to NATS subject `air3.blue` by default. If the Edge sets `S3_BLUE_BUCKET=demo-bucket`, signed URLs can use the short form `/blue/dir/object.txt`; the signature still binds the real bucket (`demo-bucket`) even though it is omitted from the path. For aliases with a default bucket, short-form parsing wins, so `/blue/demo-bucket/dir/object.txt` means key `demo-bucket/dir/object.txt` in the default bucket rather than an explicit bucket segment.
48
48
49
49
```sh
50
-
# Sign a multi-server URL for the blue connector alias.
50
+
# Sign a full-path multi-server URL for the blue connector alias.
51
51
go run ./cmd/signurl \
52
52
-base-url https://files.example.com \
53
53
-server blue \
54
54
-bucket demo-bucket \
55
55
-key dir/object.txt \
56
56
-secret "$AIR3_SIGNING_SECRET"
57
57
58
+
# If the Edge has S3_BLUE_BUCKET=demo-bucket, emit /blue/dir/object.txt.
59
+
go run ./cmd/signurl \
60
+
-base-url https://files.example.com \
61
+
-server blue \
62
+
-bucket demo-bucket \
63
+
-key dir/object.txt \
64
+
-secret "$AIR3_SIGNING_SECRET" \
65
+
-default-bucket-path
66
+
58
67
# Connector for that alias; default template renders air3.blue.
Direct servers are a separate opt-in exception for multi-server deployments. Aliases listed in `AIR3_DIRECT_SERVERS` are fetched by the Edge directly from their per-alias S3 configuration instead of using NATS and a Private Connector. That places S3 credentials and S3 network reachability on the Edge, so use it only when you intentionally accept that different trust boundary.
73
+
Direct servers are a separate opt-in exception for multi-server deployments. Aliases listed in `AIR3_DIRECT_SERVERS` are fetched by the Edge directly from their per-alias S3 configuration instead of using NATS and a Private Connector. A direct alias can also set `S3_{SUFFIX}_BUCKET` for short-form URLs, but that default bucket must be present in `S3_{SUFFIX}_ALLOWED_BUCKETS` so the Edge allowlist still validates the real bucket. Direct mode places S3 credentials and S3 network reachability on the Edge, so use it only when you intentionally accept that different trust boundary.
65
74
66
75
```mermaid
67
76
sequenceDiagram
@@ -145,7 +154,7 @@ make e2e
145
154
146
155
The smoke tests (`make smoke`) automatically verify that signed `GET`/`HEAD` requests work, expired signatures are rejected, missing objects return `404`, and most importantly, that the Edge container *cannot* bypass the system to connect directly to the private S3 server.
147
156
148
-
For a runnable multi-server example, use `make e2e-multiserver`. It exercises `blue` as a routed alias through NATS plus a Private Connector, and `direct` as an Edge direct-S3 alias using the `deploy/compose.multiserver.yaml` overlay.
157
+
For a runnable multi-server example, use `make e2e-multiserver`. It exercises `blue` as a routed alias through NATS plus a Private Connector, and `direct` as an Edge direct-S3 alias using the `deploy/compose.multiserver.yaml` overlay. Both aliases set a demo default bucket and the smoke harness signs short-form URLs for them, while retaining a full-path `green` request to show non-default aliases are unchanged.
149
158
150
159
## Performance Benchmarks & Transport Recommendations
Copy file name to clipboardExpand all lines: docs/architecture.md
+11-10Lines changed: 11 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -40,7 +40,7 @@ sequenceDiagram
40
40
41
41
## Multi-server routed flow
42
42
43
-
Multi-server mode is enabled with `AIR3_MULTI_SERVER=true`. Public URLs use `/{server}/{bucket}/{key}`; the server alias is included in signed URL validation and ticket payloads. For connector-routed aliases, the Edge renders the NATS subject from `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`), and each connector sets `AIR3_SERVER_NAME` to subscribe to its derived subject.
43
+
Multi-server mode is enabled with `AIR3_MULTI_SERVER=true`. Public URLs use `/{server}/{bucket}/{key}` unless an alias has an Edge-side default bucket from `S3_{SUFFIX}_BUCKET`. With a default such as `S3_BLUE_BUCKET=demo`, signed URLs may use `/blue/{key}`; the server alias and resolved bucket are still included in signed URL validation and ticket payloads. Short-form parsing wins for defaulted aliases, so every segment after `/{server}/` is treated as the key. For connector-routed aliases, the Edge renders the NATS subject from `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`), and each connector sets `AIR3_SERVER_NAME` to subscribe to its derived subject.
44
44
45
45
```mermaid
46
46
sequenceDiagram
@@ -52,8 +52,8 @@ sequenceDiagram
52
52
participant Green as Connector AIR3_SERVER_NAME=green
Direct-server aliases are configured on the Edge with `AIR3_DIRECT_SERVERS` or `DIRECT_SERVERS` and per-alias `S3_{SUFFIX}_*` settings. They require multi-server paths to select the alias, but they bypass NATS and the Private Connector for that alias. This is useful only when you deliberately accept that the Edge has S3 credentials and network reachability for that storage. It is not the recommended private-storage boundary.
67
+
Direct-server aliases are configured on the Edge with `AIR3_DIRECT_SERVERS` or `DIRECT_SERVERS` and per-alias `S3_{SUFFIX}_*` settings. They require multi-server paths to select the alias, but they bypass NATS and the Private Connector for that alias. A direct alias may also set `S3_{SUFFIX}_BUCKET` for short-form paths, and startup validates that default bucket against `S3_{SUFFIX}_ALLOWED_BUCKETS`. This is useful only when you deliberately accept that the Edge has S3 credentials and network reachability for that storage. It is not the recommended private-storage boundary.
68
68
69
69
```mermaid
70
70
sequenceDiagram
@@ -75,8 +75,8 @@ sequenceDiagram
75
75
participant NATS as NATS
76
76
participant Connector as Private connector
77
77
78
-
Client->>Edge: Signed GET /alpha/demo/file.txt
79
-
Edge->>Edge: Verify signature and alpha bucket allowlist
78
+
Client->>Edge: Signed GET /alpha/file.txt (S3_ALPHA_BUCKET=demo)
79
+
Edge->>Edge: Verify signature, resolved bucket, and alpha bucket allowlist
80
80
Edge->>S3: Fetch object with S3_ALPHA_* credentials
81
81
S3-->>Edge: Return object stream or metadata
82
82
Edge-->>Client: Stream response
@@ -121,14 +121,14 @@ flowchart TB
121
121
-**S3 credentials stay private by default:** In the recommended connector-routed topology, the Edge Gateway has absolutely zero knowledge of `AIR3_S3_ACCESS_KEY_ID` and `AIR3_S3_SECRET_ACCESS_KEY`. If the Edge is compromised, the attacker still cannot access your connector-only S3 buckets. Direct-server aliases intentionally opt out for their configured `S3_{SUFFIX}_*` credentials.
122
122
-**Outbound-only application traffic:** The Private Connector has no open inbound ports. It only initiates connections *out* to NATS, S3, and the Edge's ingest endpoint.
123
123
-**Separate public and ingest listeners:** Public requests hit the public listener. The private ingest listener requires strict mTLS authentication *and* a one-time ingest token generated by the Edge. The experimental HTTP/3, TCP, smux, and custom QUIC ingest transports use the same mTLS files, connector identity allowlist, and one-time token semantics as the default HTTP ingest path.
124
-
-**Defense-in-depth allowlists:** Both the Edge and the Connector strictly validate allowed bucket names before taking any action. Direct-server aliases have their own Edge-enforced `S3_{SUFFIX}_ALLOWED_BUCKETS` allowlist.
124
+
-**Defense-in-depth allowlists:** Both the Edge and the Connector strictly validate allowed bucket names before taking any action. Direct-server aliases have their own Edge-enforced `S3_{SUFFIX}_ALLOWED_BUCKETS` allowlist, and any `S3_{SUFFIX}_BUCKET` default for a direct alias must be included in that allowlist.
125
125
-**Secret-safe logging:** Logs are designed to be safe to ship anywhere. They use request IDs and high-level outcomes—never logging HMAC secrets, full URLs, ingest tokens, or raw S3 credentials.
126
126
127
127
## Data Plane vs. Control Plane
128
128
129
129
| Plane | Path | Contains | Does not contain |
130
130
| --- | --- | --- | --- |
131
-
| Public data plane | Client to edge public listener | Public `GET`/`HEAD`, signed URL claims, response bytes | S3 credentials |
131
+
| Public data plane | Client to edge public listener | Public `GET`/`HEAD`, signed URL claims, optional short-form default-bucket paths, response bytes | S3 credentials |
132
132
| Control plane | Edge to NATS to connector | Request ID, method, optional server alias, bucket, key, range, deadline, HTTPS ingest URL/fallback, one-time ingest token | Object bytes / file data |
133
133
| Private data plane | Connector to S3 | S3 object fetch and metadata requests | Public client connection |
134
134
| Direct-server data plane | Edge to configured S3 endpoint | S3 requests using `S3_{SUFFIX}_*` credentials for opt-in direct aliases | NATS tickets / Private Connector path |
@@ -137,8 +137,9 @@ flowchart TB
137
137
## Operational behavior
138
138
139
139
- NATS exclusively carries short-lived fetch tickets and control messages for connector-routed aliases. Queue-group semantics are unchanged: a ticket is delivered to one connector replica, and each connector uses a bounded local worker pool (`AIR3_CONNECTOR_WORKERS`) for concurrent ticket handling.
140
-
- With `AIR3_MULTI_SERVER=true`, the Edge parses `/{server}/{bucket}/{key}` and publishes connector-routed tickets to `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`). Connectors set `AIR3_SERVER_NAME` to derive their subscription subject and reject mismatched tickets.
141
-
- Direct-server aliases configured with `AIR3_DIRECT_SERVERS`/`DIRECT_SERVERS` bypass NATS and connector ingest for those aliases; the Edge enforces the direct alias bucket allowlist and fetches from S3 itself.
140
+
- With `AIR3_MULTI_SERVER=true`, the Edge parses `/{server}/{bucket}/{key}` or, for aliases with `S3_{SUFFIX}_BUCKET`, short-form `/{server}/{key}` paths. It publishes connector-routed tickets to `AIR3_NATS_SUBJECT_TEMPLATE` (default `air3.{server}`). Connectors set `AIR3_SERVER_NAME` to derive their subscription subject and reject mismatched tickets.
141
+
- Direct-server aliases configured with `AIR3_DIRECT_SERVERS`/`DIRECT_SERVERS` bypass NATS and connector ingest for those aliases; the Edge enforces the direct alias bucket allowlist, validates any direct default bucket against that allowlist, and fetches from S3 itself.
142
+
- Signatures bind the resolved server, bucket, and key. Omitting a configured default bucket from the public URL does not make the bucket implicit in the signature or ticket; tampering with the server alias, key, or resolved bucket still fails validation.
142
143
-`AIR3_INGEST_URL` remains the HTTPS ingest fallback/ticket URL in all modes and is used directly by the HTTP-family transports (`http`, `http1`, `http2`, `http3`) with the existing headers and body.
143
144
- Custom stream transports (`tcp`, `smux`, `quic`) use the shared MessagePack metadata frame, raw object body, and ack semantics. `smux` multiplexes those streams over persistent mTLS TCP, with one smux stream per object; direct `quic` uses `AIR3_EDGE_INGEST_QUIC_ADDR`/`AIR3_INGEST_QUIC_ADDR`.
144
145
- The Edge Gateway holds the pending client response until the Connector finishes fetching the object.
0 commit comments