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: airborne_docs/docs/dashboard/integrity.mdx
+10-4Lines changed: 10 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,8 +9,10 @@ Airborne signs every [release config](/docs/guides/verify-the-release-config-sig
9
9
10
10
Each key is an **ECDSA P-256** keypair. The **private key never leaves the server**: it cannot be downloaded and is never returned by the API. The **public key** is downloadable at any time — that is the half your apps verify with.
11
11
12
-
:::info[You already have a key]
13
-
Every application is given a keypair with the key ID `default` the moment it is created, and existing applications were backfilled with one. Signing is on out of the box; there is nothing to switch on.
12
+
:::info[New applications get a key automatically]
13
+
Every application is given a keypair with the key ID `default` when it is created, so signing is on from the first release config it serves.
14
+
15
+
Applications that **predate signing** need a one-time backfill: add `signingkeys` to [`MIGRATIONS_TO_RUN_ON_BOOT`](/docs/server/configuration#boot-time-migrations) and restart the server. It is idempotent, so it is safe to leave enabled. Until it runs, those applications serve release configs with **no** signature header — never an error in itself, but a client that requires a signature will reject them.
14
16
:::
15
17
16
18
## The key list
@@ -32,6 +34,8 @@ The page lists every key the application owns:
32
34
33
35
A new key is **not** the default — it signs nothing until you promote it. That is deliberate: it gives you a window to distribute the new public key to your apps before anything starts signing with it.
34
36
37
+
The exception is an application's **first** key, which becomes the default the moment it is created — an application with keys but no default would have nothing to sign with. You only land here if the application has no keys at all, which normally means it predates signing and has not been backfilled.
38
+
35
39
Key IDs must be unique within the application and are immutable. They must:
36
40
37
41
- contain only lowercase letters (`a-z`), digits (`0-9`), and dashes (`-`);
@@ -46,13 +50,15 @@ This is the file you ship to your apps. See [Verify the release config signature
46
50
47
51
## Set the default
48
52
49
-
**Set as default** promotes a key. From that moment, every release-config response that does not name a specific key is signed with it, and the change takes effect immediately — there is no cache to wait out.
53
+
**Set as default** promotes a key. From that moment, every release-config response that does not name a specific key is signed with it.
54
+
55
+
Airborne drops its own cached signatures and invalidates the application's release route at the CDN, so promoting a key does not leave clients on the 24-hour edge cache — they pick up the new `keyid` as soon as the invalidation propagates, usually within a minute.
50
56
51
57
Exactly one key is the default at any time; promoting a key demotes the previous one.
52
58
53
59
## Enable and disable
54
60
55
-
**Disable** takes a key out of service. Airborne will refuse to sign with it, and any request that names it in `X-Signing-Key-Id` is rejected with a **400**. Re-enabling restores it.
61
+
**Disable** takes a key out of service. Airborne will refuse to sign with it, and any request that names it in `X-Signing-Key-Id` is rejected with a **400**. Disabling also invalidates the cached release configs that key signed, so responses carrying its `keyid` stop being served from the edge. Re-enabling restores it.
56
62
57
63
Two rules keep you from locking your own apps out:
Copy file name to clipboardExpand all lines: airborne_docs/docs/guides/verify-the-release-config-signature.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,7 +123,7 @@ Omit the header and Airborne signs with the application's **default** key. To pi
123
123
X-Signing-Key-Id: release-signing-2026
124
124
```
125
125
126
-
An unknown or disabled key ID — or one belonging to a different application — is rejected with **400**.
126
+
Sending the header with an **empty** value is the same as omitting it: the default key signs. A *non-empty* key ID that is unknown or disabled — or that belongs to a different application — is rejected with **400**.
127
127
128
128
Key IDs contain only lowercase letters (`a-z`), digits (`0-9`), and single dashes. They cannot start or end with a dash.
Copy file name to clipboardExpand all lines: airborne_docs/openapi/airborne.openapi.json
+4-4Lines changed: 4 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -2888,13 +2888,13 @@
2888
2888
{
2889
2889
"name": "x-signing-key-id",
2890
2890
"in": "header",
2891
-
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, the application's default\nsigning key is used. A key ID that is invalid, unknown, disabled, or belongs to\nanother application is rejected with a 400.",
2891
+
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, or sent with an empty value,\nthe application's default signing key is used. A non-empty key ID that is\ninvalid, unknown, disabled, or belongs to another application is rejected with\na 400.",
2892
2892
"schema": {
2893
2893
"type": "string",
2894
2894
"maxLength": 50,
2895
2895
"minLength": 1,
2896
2896
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
2897
-
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, the application's default\nsigning key is used. A key ID that is invalid, unknown, disabled, or belongs to\nanother application is rejected with a 400."
2897
+
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, or sent with an empty value,\nthe application's default signing key is used. A non-empty key ID that is\ninvalid, unknown, disabled, or belongs to another application is rejected with\na 400."
2898
2898
}
2899
2899
}
2900
2900
],
@@ -3012,13 +3012,13 @@
3012
3012
{
3013
3013
"name": "x-signing-key-id",
3014
3014
"in": "header",
3015
-
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, the application's default\nsigning key is used. A key ID that is invalid, unknown, disabled, or belongs to\nanother application is rejected with a 400.",
3015
+
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, or sent with an empty value,\nthe application's default signing key is used. A non-empty key ID that is\ninvalid, unknown, disabled, or belongs to another application is rejected with\na 400.",
3016
3016
"schema": {
3017
3017
"type": "string",
3018
3018
"maxLength": 50,
3019
3019
"minLength": 1,
3020
3020
"pattern": "^[a-z0-9]+(-[a-z0-9]+)*$",
3021
-
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, the application's default\nsigning key is used. A key ID that is invalid, unknown, disabled, or belongs to\nanother application is rejected with a 400."
3021
+
"description": "ID of the signing key to sign the response with. This is the readable ID chosen\nwhen the key was created. Optional — when omitted, or sent with an empty value,\nthe application's default signing key is used. A non-empty key ID that is\ninvalid, unknown, disabled, or belongs to another application is rejected with\na 400."
0 commit comments