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
For more information on cost calculation, see the [cost tracking guide]({{< link-hextra path="/llm/cost-controls/cost-tracking/" >}}).
197
234
235
+
<!--TODO dollar budget
236
+
198
237
## Enforce a dollar budget
199
238
200
239
The budgets in the previous sections are measured in *tokens*. If you configure a [model cost catalog]({{< link-hextra path="/llm/cost-controls/costs/" >}}), {{< reuse "agw-docs/snippets/agentgateway.md" >}} computes the realized USD cost of each request and exposes it to CEL as `llm.cost`. You can then rate limit on *dollars* directly, which enforces a true spend cap regardless of which model or input/output token mix each user hits.
@@ -230,7 +269,7 @@ The budgets in the previous sections are measured in *tokens*. If you configure
@@ -258,6 +297,8 @@ The budgets in the previous sections are measured in *tokens*. If you configure
258
297
To budget on a single cost component instead of the total, use that field in the expression. For example, `cost: 'uint(llm.cost.output * 1000000)'` budgets only on output-token spend.
Copy file name to clipboardExpand all lines: assets/agw-docs/pages/agentgateway/llm/virtual-keys.md
+127-3Lines changed: 127 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -30,7 +30,7 @@ flowchart LR
30
30
31
31
When a request arrives:
32
32
33
-
1. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} validates the API key, extracts the user ID from a request header, and checks the request against the user's token budget.
33
+
1. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} validates the API key, extracts the user ID from the key's metadata, and checks the request against the user's token budget.
34
34
2. If budget is available:
35
35
1. The request proceeds to the LLM.
36
36
2. Agentgateway tracks token usage and deducts tokens from the user's budget.
@@ -53,6 +53,60 @@ This example creates two virtual keys (for Alice and Bob) with independent daily
53
53
54
54
### Create API keys for users
55
55
56
+
{{< version exclude-if="1.3.x,1.2.x,1.1.x,1.0.x,2.2.x" >}}
57
+
Store your virtual keys in a Kubernetes ConfigMap, with one entry per user. Because a ConfigMap is not confidential, each entry stores a SHA-256 *hash* of the API key (`keyHash`) rather than the raw key. Clients still send the raw key in the `Authorization: Bearer` header. {{< reuse "agw-docs/snippets/agentgateway-capital.md" >}} hashes the presented key and compares it to the stored hash, so the plaintext key never has to exist in the cluster.
58
+
59
+
> [!IMPORTANT]
60
+
> ConfigMaps with hashed keys (as opposed to Secrets) are the recommended way to store virtual keys. If you need to use Kubernetes Secrets, refer to the [API key authentication guide]({{< link-hextra path="/security/apikey/" >}}) for an example.
61
+
62
+
1. Generate a `sha256:<hex>` hash for each user's API key. The hash is computed over the exact key bytes, so do not include a trailing newline.
63
+
64
+
```sh
65
+
printf'%s''sk-alice-abc123def456'| sha256sum | awk '{print "sha256:"$1}'# alice
66
+
printf'%s''sk-bob-xyz789uvw012'| sha256sum | awk '{print "sha256:"$1}'# bob
67
+
```
68
+
69
+
2. Create a ConfigMap that stores the hash and metadata for each user. Add a label so that the authentication policy can select the ConfigMap in the next step.
|`metadata.labels`| A label that the authentication policy uses to select this ConfigMap. Because ConfigMap sources are selected by label, this label is required. |
103
+
|`data.<name>`| Each entry in `data` represents a user. The value is a JSON object with a `keyHash` and optional `metadata`. |
104
+
|`keyHash`| A SHA-256 hash of the user's API key, in `sha256:<hex>` format. The raw key is never stored. |
105
+
|`metadata.user_id`| The user identifier that rate limiting and metrics policies read (as `apiKey.user_id`) to attribute usage per user. |
106
+
107
+
{{< /version >}}
108
+
109
+
{{< version include-if="1.3.x,1.2.x,1.1.x,1.0.x,2.2.x" >}}
56
110
Create an API key secret that stores keys and metadata for each user.
57
111
58
112
```yaml,paths="virtual-keys"
@@ -88,9 +142,44 @@ EOF
88
142
|`stringData.<name>`| Each key in `stringData` represents a user. The value is a JSON object containing the API key and metadata. |
89
143
|`key`| The API key value that users include in their `Authorization: Bearer` header. |
90
144
|`metadata.user_id`| The user identifier extracted by rate limiting policies to enforce per-user budgets. |
145
+
{{< /version >}}
91
146
92
147
### Configure API key authentication
93
148
149
+
{{< version exclude-if="1.3.x,1.2.x,1.1.x,1.0.x,2.2.x" >}}
150
+
Create an {{< reuse "agw-docs/snippets/policy.md" >}} that requires API key authentication for all requests to the gateway. Unlike Secrets, which you can reference directly by name, ConfigMaps can be selected only by label. Use `configMapSelector` to match every ConfigMap that carries the label you added in the previous step, whether that is a single ConfigMap or several.
|`targetRefs`| Apply the policy to the entire Gateway so all routes require API keys. |
178
+
|`apiKeyAuthentication.mode`| Set to `Strict` to require a valid API key for all requests. |
179
+
|`configMapSelector.matchLabels`| Selects all ConfigMaps that carry the given labels, combining their keys. Every entry in a selected ConfigMap must use `keyHash`; a raw `key` value is rejected because ConfigMaps are not confidential. |
180
+
{{< /version >}}
181
+
182
+
{{< version include-if="1.3.x,1.2.x,1.1.x,1.0.x,2.2.x" >}}
94
183
Create an {{< reuse "agw-docs/snippets/policy.md" >}} that requires API key authentication for all requests to the gateway. You can source the API keys from a single Secret with `secretRef`, or from multiple Secrets selected by label with `secretSelector`. Use `secretSelector` when you want to spread keys across many Secrets, such as one Secret per team or tenant, instead of maintaining a single Secret.
95
184
96
185
{{< tabs >}}
@@ -161,6 +250,7 @@ EOF
161
250
|`apiKeyAuthentication.mode`| Set to `Strict` to require a valid API key for all requests. |
162
251
|`secretRef.name`| References a single Secret containing API keys and user metadata. Use this or `secretSelector`, not both. |
163
252
|`secretSelector.matchLabels`| Selects all Secrets that carry the given labels, combining their keys. Use instead of `secretRef` when keys are spread across multiple Secrets. Secret-only. |
253
+
{{< /version >}}
164
254
165
255
### Configure per-key token budgets
166
256
@@ -687,8 +777,40 @@ For more information on cost tracking, see the [cost tracking guide]({{< link-he
687
777
688
778
Provide different budget tiers for free, standard, and premium users.
689
779
690
-
1. Add tier metadata to each API key in the Secret.
780
+
1. Add tier metadata to each API key.
781
+
782
+
{{< version exclude-if="1.3.x,1.2.x,1.1.x,1.0.x,2.2.x" >}}
783
+
Store the keys in a ConfigMap, using the `keyHash` of each key. Generate each hash with `printf '%s' '<key>' | sha256sum | awk '{print "sha256:"$1}'`.
0 commit comments