aws changedmanage-claude/wif-providers/aws
Nearest release: v2.1.309, published 3 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.
Recorded here
Lines+177added
Lines−175removed
From line
135
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits12to this page, all time
The whole hunk
from line 135, old and new numbered
/
from line 135
135135 }'
136136 ```
137137
138 ```bash CLI
139 export ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
140 aws sts get-web-identity-token \
141 --region us-east-1 \
142 --audience "https://api.anthropic.com" \
143 --signing-algorithm RS256 \
144 --duration-seconds 900 \
145 --query WebIdentityToken --output text > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
146
147 # ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
148 # ANTHROPIC_SERVICE_ACCOUNT_ID, and ANTHROPIC_WORKSPACE_ID are read from the environment
149 ant messages create \
150 --model claude-opus-5-5 \
151 --max-tokens 1024 \
152 --message '{role: user, content: "Hello from AWS"}'
153 ```
154
138155 ```python Python
139156 import os
140157
from line 230
213230 }
214231 ```
215232
233 ```csharp C#
234 using Amazon.SecurityToken;
235 using Amazon.SecurityToken.Model;
236 // ...
237 using Anthropic.Credentials;
238 // ...
239
240 var credentials = new WorkloadIdentityCredentials(new WorkloadIdentityOptions
241 {
242 FederationRuleId = Environment.GetEnvironmentVariable("ANTHROPIC_FEDERATION_RULE_ID")!,
243 OrganizationId = Environment.GetEnvironmentVariable("ANTHROPIC_ORGANIZATION_ID"),
244 ServiceAccountId = Environment.GetEnvironmentVariable("ANTHROPIC_SERVICE_ACCOUNT_ID"),
245 WorkspaceId = Environment.GetEnvironmentVariable("ANTHROPIC_WORKSPACE_ID"),
246 IdentityTokenProvider = new StsTokenProvider(),
247 });
248 using var client = new AnthropicClient(new ClientOptions { Credentials = credentials });
249
250 var message = await client.Messages.Create(new()
251 {
252 Model = Model.ClaudeOpus5_5,
253 MaxTokens = 1024,
254 Messages = [new UserMessageParam { Content = "Hello from AWS" }],
255 });
256 foreach (var block in message.Content)
257 {
258 if (block.Value is TextBlock textBlock)
259 {
260 Console.WriteLine(textBlock.Text);
261 }
262 }
263
264 class StsTokenProvider : IIdentityTokenProvider
265 {
266 private readonly AmazonSecurityTokenServiceClient _sts = new(Amazon.RegionEndpoint.USEast1);
267
268 public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
269 {
270 var resp = await _sts.GetWebIdentityTokenAsync(new GetWebIdentityTokenRequest
271 {
272 Audience = ["https://api.anthropic.com"],
273 SigningAlgorithm = "RS256",
274 DurationSeconds = 900,
275 }, ct);
276 return resp.WebIdentityToken;
277 }
278 }
279 ```
280
216281 ```go Go
217282 ctx := context.TODO()
218283 cfg, err := config.LoadDefaultConfig(ctx, config.WithRegion("us-east-1"))
from line 337
272337 import software.amazon.awssdk.services.sts.model.GetWebIdentityTokenRequest;
273338
274339 void main() {
275 StsClient sts = StsClient.builder().region(Region.US_EAST_1).build();
340 StsClient sts = StsClient.builder()
341 .region(Region.US_EAST_1)
342 .build();
276343
277344 // The Java SDK takes the token itself or a file path, not a function; with
278345 // source("value"), path(...) holds the token. The SDK sends that same token
from line 348
281348 // process, pass source("file") and write a new token to the file before
282349 // each refresh.
283350 String stsToken = sts.getWebIdentityToken(
284 GetWebIdentityTokenRequest.builder()
285 .audience("https://api.anthropic.com")
286 .signingAlgorithm("RS256")
287 .durationSeconds(900)
288 .build())
289 .webIdentityToken();
351 GetWebIdentityTokenRequest.builder()
352 .audience("https://api.anthropic.com")
353 .signingAlgorithm("RS256")
354 .durationSeconds(900)
355 .build())
356 .webIdentityToken();
290357
291358 AnthropicClient client = AnthropicOkHttpClient.builder()
292 .configurationProvider(InMemoryProfileConfigProvider.of(ProfileConfig.builder()
293 .organizationId(System.getenv("ANTHROPIC_ORGANIZATION_ID"))
294 .workspaceId(System.getenv("ANTHROPIC_WORKSPACE_ID"))
295 .authentication(AuthenticationConfig.builder()
296 .type(AuthenticationType.OIDC_FEDERATION)
297 .federationRuleId(System.getenv("ANTHROPIC_FEDERATION_RULE_ID"))
298 .serviceAccountId(System.getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"))
299 .identityToken(IdentityTokenConfig.builder()
300 .source("value")
301 .path(stsToken)
302 .build())
303 .build())
304 .build()))
305 .build();
359 .configurationProvider(InMemoryProfileConfigProvider.of(ProfileConfig.builder()
360 .organizationId(System.getenv("ANTHROPIC_ORGANIZATION_ID"))
361 .workspaceId(System.getenv("ANTHROPIC_WORKSPACE_ID"))
362 .authentication(AuthenticationConfig.builder()
363 .type(AuthenticationType.OIDC_FEDERATION)
364 .federationRuleId(System.getenv("ANTHROPIC_FEDERATION_RULE_ID"))
365 .serviceAccountId(System.getenv("ANTHROPIC_SERVICE_ACCOUNT_ID"))
366 .identityToken(IdentityTokenConfig.builder()
367 .source("value")
368 .path(stsToken)
369 .build())
370 .build())
371 .build()))
372 .build();
306373
307374 var message = client.messages().create(MessageCreateParams.builder()
308 .model(Model.CLAUDE_OPUS_5_5)
309 .maxTokens(1024)
310 .addUserMessage("Hello from AWS")
311 .build());
375 .model(Model.CLAUDE_OPUS_5_5)
376 .maxTokens(1024)
377 .addUserMessage("Hello from AWS")
378 .build());
312379
313380 IO.println(message.content());
314381 }
315382 ```
316383
317 ```csharp C#
318 using Amazon.SecurityToken;
319 using Amazon.SecurityToken.Model;
320 // ...
321 using Anthropic.Credentials;
322 // ...
323
324 var credentials = new WorkloadIdentityCredentials(new WorkloadIdentityOptions
325 {
326 FederationRuleId = Environment.GetEnvironmentVariable("ANTHROPIC_FEDERATION_RULE_ID")!,
327 OrganizationId = Environment.GetEnvironmentVariable("ANTHROPIC_ORGANIZATION_ID"),
328 ServiceAccountId = Environment.GetEnvironmentVariable("ANTHROPIC_SERVICE_ACCOUNT_ID"),
329 WorkspaceId = Environment.GetEnvironmentVariable("ANTHROPIC_WORKSPACE_ID"),
330 IdentityTokenProvider = new StsTokenProvider(),
331 });
332 using var client = new AnthropicClient(new ClientOptions { Credentials = credentials });
333
334 var message = await client.Messages.Create(new()
335 {
336 Model = Model.ClaudeOpus5_5,
337 MaxTokens = 1024,
338 Messages = [new UserMessageParam { Content = "Hello from AWS" }],
339 });
340 foreach (var block in message.Content)
341 {
342 if (block.Value is TextBlock textBlock)
343 {
344 Console.WriteLine(textBlock.Text);
345 }
346 }
347
348 class StsTokenProvider : IIdentityTokenProvider
349 {
350 private readonly AmazonSecurityTokenServiceClient _sts = new(Amazon.RegionEndpoint.USEast1);
351
352 public async Task<string> GetIdentityTokenAsync(CancellationToken ct = default)
353 {
354 var resp = await _sts.GetWebIdentityTokenAsync(new GetWebIdentityTokenRequest
355 {
356 Audience = ["https://api.anthropic.com"],
357 SigningAlgorithm = "RS256",
358 DurationSeconds = 900,
359 }, ct);
360 return resp.WebIdentityToken;
361 }
362 }
363 ```
364
365 ```bash CLI
366 export ANTHROPIC_IDENTITY_TOKEN_FILE=$(mktemp)
367 aws sts get-web-identity-token \
368 --region us-east-1 \
369 --audience "https://api.anthropic.com" \
370 --signing-algorithm RS256 \
371 --duration-seconds 900 \
372 --query WebIdentityToken --output text > "$ANTHROPIC_IDENTITY_TOKEN_FILE"
373
374 # ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
375 # ANTHROPIC_SERVICE_ACCOUNT_ID, and ANTHROPIC_WORKSPACE_ID are read from the environment
376 ant messages create \
377 --model claude-opus-5-5 \
378 --max-tokens 1024 \
379 --message '{role: user, content: "Hello from AWS"}'
380 ```
381
382384 ```php PHP
383385 use Anthropic\Client;
384386 use Anthropic\Lib\Credentials\CredentialResult;
from line 480
478480JSON
479481```
480482
481A successful exchange returns an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason and see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange); the most common AWS-side cause is an `iss` mismatch (the per-account STS issuer URL must match the registered `issuer_url` exactly).
483A successful exchange returns an `access_token` starting with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason and see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange); the most common AWS-side cause is an `iss` mismatch (the per-account STS issuer URL must match the registered `issuer_url` exactly).
482484
483485## Use EKS projected service-account tokens
484486
from line 643
641643 }'
642644 ```
643645
646 ```bash CLI
647 # Reads ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
648 # ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID, and ANTHROPIC_IDENTITY_TOKEN_FILE
649 ant messages create \
650 --model claude-opus-5-5 \
651 --max-tokens 1024 \
652 --message '{role: user, content: "Hello from EKS"}'
653 ```
654
644655 ```python Python
645656 import os
646657
from line 707
696707 }
697708 ```
698709
710 ```csharp C#
711 // Reads ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
712 // ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID, and ANTHROPIC_IDENTITY_TOKEN_FILE
713 // from the pod's environment.
714 using var client = new AnthropicClient();
715
716 var message = await client.Messages.Create(new()
717 {
718 Model = Model.ClaudeOpus5_5,
719 MaxTokens = 1024,
720 Messages = [new UserMessageParam { Content = "Hello from EKS" }],
721 });
722 foreach (var block in message.Content)
723 {
724 if (block.Value is TextBlock textBlock)
725 {
726 Console.WriteLine(textBlock.Text);
727 }
728 }
729 ```
730
699731 ```go Go
700732 tokenPath := os.Getenv("ANTHROPIC_IDENTITY_TOKEN_FILE")
701733
from line 770
738770 AnthropicClient client = AnthropicOkHttpClient.fromEnv();
739771
740772 var message = client.messages().create(MessageCreateParams.builder()
741 .model(Model.CLAUDE_OPUS_5_5)
742 .maxTokens(1024)
743 .addUserMessage("Hello from EKS")
744 .build());
773 .model(Model.CLAUDE_OPUS_5_5)
774 .maxTokens(1024)
775 .addUserMessage("Hello from EKS")
776 .build());
745777
746778 IO.println(message.content());
747779 ```
748780
749 ```csharp C#
750 // Reads ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
751 // ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID, and ANTHROPIC_IDENTITY_TOKEN_FILE
752 // from the pod's environment.
753 using var client = new AnthropicClient();
754
755 var message = await client.Messages.Create(new()
756 {
757 Model = Model.ClaudeOpus5_5,
758 MaxTokens = 1024,
759 Messages = [new UserMessageParam { Content = "Hello from EKS" }],
760 });
761 foreach (var block in message.Content)
762 {
763 if (block.Value is TextBlock textBlock)
764 {
765 Console.WriteLine(textBlock.Text);
766 }
767 }
768 ```
769
770 ```bash CLI
771 # Reads ANTHROPIC_FEDERATION_RULE_ID, ANTHROPIC_ORGANIZATION_ID,
772 # ANTHROPIC_SERVICE_ACCOUNT_ID, ANTHROPIC_WORKSPACE_ID, and ANTHROPIC_IDENTITY_TOKEN_FILE
773 ant messages create \
774 --model claude-opus-5-5 \
775 --max-tokens 1024 \
776 --message '{role: user, content: "Hello from EKS"}'
777 ```
778
779781 ```php PHP
780782 use Anthropic\Client;
781783
from line 835
833835JSON
834836```
835837
836A successful exchange returns an `access_token` beginning with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason and see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange); the most common EKS-side cause is the projected token's `aud` not matching the rule (project a token with `audience: https://api.anthropic.com`, not the IRSA default `sts.amazonaws.com`).
838A successful exchange returns an `access_token` starting with `sk-ant-oat01-` and an `expires_in` value in seconds. If the exchange fails with the opaque `401` `authentication_error` response (message `Authentication failed`), check the [authentication history page](https://platform.claude.com/settings/workload-identity-federation?tab=history) in the Claude Console for the deny reason and see [Troubleshoot a failed exchange](https://platform.claude.com/docs/en/manage-claude/wif-reference#troubleshoot-a-failed-exchange); the most common EKS-side cause is the projected token's `aud` not matching the rule (project a token with `audience: https://api.anthropic.com`, not the IRSA default `sts.amazonaws.com`).
837839
838840## Scope your rule
839841
No line in this hunk matches that.