Files
windmill/backend/windmill-ai/src/credentials.rs
T
6c8fd6cfe2 feat: per-user Anthropic Workload Identity Federation for Windmill AI (#11998)
* feat: authenticate Windmill AI to Anthropic with per-user Workload Identity Federation

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: reject WIF-only Anthropic resources in agent steps, scale token refresh margin

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* refactor: move Anthropic WIF to a separate anthropic_federated resource type

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: point agent steps at an anthropic resource instead of a federated one

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: report a federated resource missing a field instead of reading it as standard

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* feat: count Anthropic federated token exchanges in feature_usage

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: update ee-repo-ref to 747336910e5c7498544613ad7863cea59f4db6a1

This commit updates the EE repository reference after PR #923 was merged in windmill-ee-private.

Previous ee-repo-ref: 3ea70adff288448f7318ff20b41225fd726ca8d1

New ee-repo-ref: 747336910e5c7498544613ad7863cea59f4db6a1

Automated by sync-ee-ref workflow.

* feat: authenticate AI agent steps with anthropic_federated resources (#11999)

* feat: authenticate AI agent steps with anthropic_federated resources

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep get_id_token's signature for its EE callers

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* chore: update ee-repo-ref to 747336910e5c7498544613ad7863cea59f4db6a1

This commit updates the EE repository reference after PR #923 was merged in windmill-ee-private.

Previous ee-repo-ref: 3ea70adff288448f7318ff20b41225fd726ca8d1

New ee-repo-ref: 747336910e5c7498544613ad7863cea59f4db6a1

Automated by sync-ee-ref workflow.

* feat: switch between anthropic and anthropic_federated when adding a resource

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix: keep registryCcCapable's doc comment on it

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
2026-10-25 16:37:29 +01:00

53 lines
2.4 KiB
Rust

use std::collections::HashMap;
use crate::ai_providers::{AIPlatform, AIProvider};
/// Resolved provider credentials shared by API proxy and worker execution.
///
/// Raw API resources and worker agent payloads convert into this shape at their
/// execution boundaries. Request-specific state such as the selected model stays
/// outside this type.
#[derive(Clone, Debug)]
pub struct ProviderCredentials {
pub provider: AIProvider,
pub base_url: String,
pub api_key: Option<String>,
pub access_token: Option<String>,
pub organization_id: Option<String>,
pub user: Option<String>,
pub region: Option<String>,
pub aws_access_key_id: Option<String>,
pub aws_secret_access_key: Option<String>,
pub aws_session_token: Option<String>,
/// AWS IAM role to assume through Windmill's OIDC provider. Only consulted
/// when no bearer key and no explicit IAM keys are set — see
/// [`crate::ai_bedrock::bedrock_oidc_role_to_assume`]. The API proxy
/// exchanges it for temporary keys before it builds the request; the worker
/// exchanges it at the Bedrock call, because only the API can sign an OIDC
/// token.
///
/// The two paths therefore present different tokens to AWS: the proxy a
/// workspace claim with `sub = "<email>::<workspace>"`, the worker the job
/// claim `/oidc/token` issues, `sub = "<email>::<path>::<flow_path>::<workspace>"`.
/// A role trust policy that conditions on `sub` has to admit both, or only
/// one of the copilot and the AI agent step will be able to assume the role.
pub oidc_role_arn: Option<String>,
/// Anthropic Workload Identity Federation settings, from an `anthropic_federated`
/// resource. The API proxy exchanges an OIDC token minted for the requesting
/// user for a short-lived access token, which then goes out as `access_token`.
pub anthropic_federation: Option<AnthropicFederation>,
pub platform: AIPlatform,
pub custom_headers: HashMap<String, String>,
}
/// The identifiers a Claude Console federation rule needs in a token exchange.
/// None of them is a secret: what authorises the exchange is the OIDC token.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub struct AnthropicFederation {
pub federation_rule_id: String,
pub organization_id: String,
pub service_account_id: String,
/// Required by Anthropic only when the rule is enabled in several workspaces.
pub workspace_id: Option<String>,
}