Configure credential injection for Agent Sandbox
Automatically replace placeholder credentials with real ones in Agent Sandbox egress traffic by defining tokenTransformation rules in a SecurityProfile. Applications call external APIs with placeholder credentials, and the egress gateway injects the real credentials at forwarding time.
Overview
In AI Agent scenarios, sandbox code often comes from untrusted sources. Embedding real API keys or cloud account AccessKeys in the sandbox risks credential leakage. Credential injection dynamically replaces credentials at the egress gateway, providing the following security guarantees:
-
Sandbox applications hold only placeholder credentials (for example,
FAKE_AK) and cannot directly call external services. -
Real credentials are stored within the cluster (in Kubernetes Secrets or a
CredentialProvider) and managed centrally by the platform. -
The gateway automatically replaces credentials and recalculates the signature when forwarding requests, making the process transparent to the sandbox application.
-
The
AgentIdentityauthorization mechanism provides fine-grained control over which credentials each agent identity can use.
Credential injection supports two modes. Choose a mode based on the target service type:
|
Mode |
Use cases |
Description |
|
API key injection |
Third-party LLM services (for example, OpenAI, Tongyi Qianwen) |
Replaces placeholder tokens in requests with real API keys. |
|
Alibaba Cloud STS credential injection |
Calling Alibaba Cloud OpenAPI |
Replaces the AK, SK, and STS token and recalculates the request signature. |
How it works
The following diagram illustrates how egress traffic credential injection forwards requests and replaces credentials.
-
Request initiation: A sandbox application initiates an egress request by using a placeholder credential. The
traffic-proxysidecar transparently intercepts the request and forwards it to theegress-gateway. -
Policy evaluation: The
egress-gatewaysends the request metadata to thetraffic-extensionservice, which matches it against theSecurityProfilerules in the namespace. -
Credential retrieval: If the request matches a
tokenTransformationrule,traffic-extensionretrieves the real credential through aCredentialProvider. -
Credential replacement: The
traffic-extensionservice replaces the placeholder credential in the request header. For the Alibaba Cloud STS mode, it also recalculates the request signature based on the real AK/SK. -
Forwarding and response: The
egress-gatewayforwards the request with the rewritten header to the target service. The response returns to the sandbox application through the same path.
Related resource objects
This feature relies on five Custom Resources (CRs) that work together. The procedures below guide you through creating each one in order.
|
Resource object |
Description |
|
|
Defines an agent identity. A |
|
|
Defines the source of real credentials. In API key mode, it reads from a Kubernetes Secret. In Alibaba Cloud STS mode, it assumes a RAM role through RRSA to obtain temporary credentials. |
|
|
Defines permission rules that declare which |
|
|
Binds an |
|
|
Defines |
Prerequisites
-
Cluster version 1.30 or later.
-
On the Add-ons page of your cluster, verify the versions and configurations of the following components:
-
ack-agent-identity: Version >= 0.2.0. -
ack-agent-sandbox-controller: Version >= 0.5.16, andidentityProvideris enabled in the configuration. -
ack-sandbox-manager: Version >= 0.6.4, andenhancedTrafficManagementis enabled in the configuration.
-
Configure credential injection
Regardless of which credential injection mode you use, first create an AgentIdentity CR to define the agent identity. Sandbox instances associate with this identity to enable credential injection.
The following steps use kubectl. Before you begin, ensure you have a kubeconfig file configured for your target ACK cluster. For more information, see Connect to ACK clusters by using kubectl.
-
Save the following content as
agent-identity.yaml, and run thekubectl apply -f agent-identity.yamlcommand to create the AgentIdentity resource.apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: AgentIdentity metadata: name: my-agent # The name of the agent identity, referenced in subsequent configurations. namespace: <YOUR_NAMESPACE> spec: description: "Example AI Agent identity" -
After creating the
AgentIdentity, choose a mode based on your target service type:-
API key injection mode: Suitable for injecting API keys for third-party API services, such as LLM services.
-
Alibaba Cloud STS credential injection mode: Suitable for sandbox applications that call Alibaba Cloud OpenAPI, with automatic signature recalculation.
API key injection
The following end-to-end procedure uses
httpbin.orgas an example verification target. Replace it with your actual target domain name.-
Save the following content as
llm-api-key-secret.yamland run thekubectl apply -fcommand to create a Secret to store the API Key.apiVersion: v1 kind: Secret metadata: name: llm-api-key namespace: <YOUR_NAMESPACE> type: Opaque stringData: apiKey: "sk-xxxxxxxxxxxxxxxx" # Replace with your real API key. -
Save the following content as
credential-provider-apikey.yamland run thekubectl apply -fcommand to create a CredentialProvider that references the Secret.apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: CredentialProvider metadata: name: llm-api-key namespace: <YOUR_NAMESPACE> spec: type: APIKey apiKey: source: provider: Kubernetes kubernetes: secretRef: name: llm-api-key # The name of the Secret created in the previous step. keyName: apiKey # The field name in the Secret that contains the API key.NoteThe
secretRef.nameparameter supports the use of template variables to dynamically reference Secret names. For more information, see CredentialProvider template variables. -
Save the following content as
agent-role-apikey.yamland run thekubectl apply -fcommand to create an AgentRole and an AgentRoleBinding, authorizing the Agent identity to obtain the credential from this CredentialProvider.apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: AgentRole metadata: name: get-llm-key namespace: <YOUR_NAMESPACE> spec: rules: - effect: Allow action: "GetResourceCredential" resource: "CredentialProvider/llm-api-key" # The name of the CredentialProvider created in the previous step. --- apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: AgentRoleBinding metadata: name: my-agent-get-llm-key namespace: <YOUR_NAMESPACE> spec: agentRoleRef: apiGroup: agentidentity.alibabacloud.com kind: AgentRole name: get-llm-key subjects: - authorizationType: "Agent" agentAuthorizationConfiguration: agentName: my-agent # Must be the same as the AgentIdentity name. -
Save the following content as
security-profile-apikey.yamland run thekubectl apply -fcommand to create a SecurityProfile and configure a token transformation rule.The following example shows that when the Authorization header starts with Bearer, the system automatically replaces it with the actual API Key based on the
valueTemplate. ({{ .Token }}is a fixed syntax).apiVersion: agents.kruise.io/v1alpha1 kind: SecurityProfile metadata: name: inject-llm-key namespace: <YOUR_NAMESPACE> spec: selector: matchLabels: security.agents.kruise.io/agent-name: my-agent # Must be the same as the AgentIdentity name. rules: - name: inject-openai-key match: - domains: - "httpbin.org" # Example for verification. Replace with your target domain in production. actions: tokenTransformation: type: ApiKey credentialRef: kind: CredentialProvider name: llm-api-key apiKey: when: header: Authorization pattern: "^Bearer .+" targetHeader: Authorization valueTemplate: "Bearer {{ .Token }}"For a description of key fields, see tokenTransformation fields.
-
Save the following content as
sandboxset-apikey.yamland run thekubectl apply -fcommand to create a SandboxSet and declare theenhanced-traffic-policymode to enable enhanced traffic management.apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet metadata: name: apikey-test namespace: <YOUR_NAMESPACE> spec: replicas: 2 runtimes: - name: csi - name: agent-runtime template: metadata: annotations: network.alibabacloud.com/network-policy-mode: enhanced-traffic-policy labels: alibabacloud.com/acs: "true" spec: automountServiceAccountToken: false containers: - name: sandbox image: registry-cn-hangzhou.ack.aliyuncs.com/acs/acs-ephemeraljob-tools-asi:v0.6 # Replace with your business image. resources: requests: cpu: "2" memory: 2Gi limits: cpu: "2" memory: 2GiWait for the Pod to be ready, and confirm that the Sandbox in the SandboxSet is in the
Runningstate:kubectl get sandbox -n <YOUR_NAMESPACE>Expected output:
NAME STATUS AGE CLAIMED apikey-test-xxxxx Running 60s false apikey-test-yyyyy Running 60s false -
Save the following content as
sandboxclaim-apikey.yamland run thekubectl apply -fcommand to apply the SandboxClaim, which allocates a Sandbox and associates an Agent identity.apiVersion: agents.kruise.io/v1alpha1 kind: SandboxClaim metadata: name: apikey-test-claim namespace: <YOUR_NAMESPACE> spec: templateName: apikey-test replicas: 1 claimTimeout: 5m ttlAfterCompleted: 15m labels: security.agents.kruise.io/agent-name: my-agent # Associate with the AgentIdentity.Verify that the
CLAIMEDstate of one of the Sandboxes changes totrue:kubectl get sandbox -n <YOUR_NAMESPACE>Expected output:
NAME STATUS AGE CLAIMED apikey-test-xxxxx Running 2m true apikey-test-yyyyy Running 2m false -
Log in to the claimed Sandbox Pod and send a request by using the placeholder token to verify that the API key injection is successful.
CLAIMED_POD=$(kubectl get sandbox -n <YOUR_NAMESPACE> \ -l agents.kruise.io/sandbox-claimed=true,agents.kruise.io/sandbox-template=apikey-test \ -o jsonpath='{.items[0].metadata.name}') kubectl exec $CLAIMED_POD -n <YOUR_NAMESPACE> -c sandbox -- \ curl -s http://httpbin.org/headers -H "Authorization: Bearer fake-token"In the expected output, the
Authorizationheader has been replaced with the actual API Key:{ "headers": { "Accept": "*/*", "Authorization": "Bearer sk-xxxxxxxxxxxxxxxx", "Host": "httpbin.org", "User-Agent": "curl/7.61.1", ... } }
STS credential injection
The system transparently replaces the AK, SK, and STS token in the request and recalculates the request signature. The sandbox application can call cloud services normally by using a standard Alibaba Cloud SDK with fake credentials. This procedure provides an end-to-end example that grants read-only access to a cluster.
Prerequisites
-
The RAM Roles for Service Accounts (RRSA) feature is enabled for the cluster. This is required for the Alibaba Cloud STS mode. For instructions, see Use RRSA to configure RAM permissions for a ServiceAccount and isolate Pod permissions.
-
Enable HTTPS traffic management (the Alibaba Cloud SDK uses HTTPS by default), and in the
enhancedTrafficManagement.tlsTermination.includeHostsparameter of the ack-sandbox-manager component, configure*.aliyuncs.comor*.
Procedure
NoteThis mode relies on the ack-agent-identity component to obtain temporary credentials by accessing the
AssumeRoleWithOIDCAPI of the STS service. Please go to the Quota Center to apply for an access quota for theAssumeRoleWithOIDCAPI based on the scale of your Sandbox instances to avoid credential injection failures caused by an insufficient quota.-
In the RAM console, create a Resource Access Management (RAM) role, such as
ack-agent-identity-sample-role, and configure a trust policy to authorize the ack-agent-identity component to assume this role via RRSA. Replace<oidc_issuer_url>and<oidc_provider_arn>in the following template with the RRSA OIDC information of the cluster. You can obtain this information from the RRSA OIDC section on the basic information page of the cluster.{ "Statement": [ { "Action": "sts:AssumeRole", "Condition": { "StringEquals": { "oidc:aud": "sts.aliyuncs.com", "oidc:iss": "<oidc_issuer_url>", "oidc:sub": [ "system:serviceaccount:ack-agent-identity:credential-provider" ] } }, "Effect": "Allow", "Principal": { "Federated": [ "<oidc_provider_arn>" ] } } ], "Version": "1" }Grant the RAM role the required permission policy (such as
AliyunCSReadOnlyAccess). -
Save the following content as
credential-provider-sts.yamland run the kubectl apply -f command to create a CredentialProvider that references the RAM role. Thepolicyfield defines the permission scope of the issued STS Token, which must be a subset of the role's permissions.apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: CredentialProvider metadata: name: aliyun-cs-readonly namespace: <YOUR_NAMESPACE> spec: type: RAM ram: source: provider: RRSA rrsa: roleName: ack-agent-identity-sample-role policy: | { "Statement": [ { "Action": [ "cs:Describe*", "cs:Get*", "cs:List*" ], "Effect": "Allow", "Resource": ["*"] } ], "Version": "1" }The
policysupports template variables to dynamically adjust permissions based on the Sandbox instance. For the definitions of these variables, see CredentialProvider template variables. -
Save the following content as
agent-role-sts.yamland run the kubectl apply -f command to authorize the Agent identity to obtain the CredentialProvider credential.apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: AgentRole metadata: name: get-aliyun-sts namespace: <YOUR_NAMESPACE> spec: rules: - effect: Allow action: "GetResourceCredential" resource: "CredentialProvider/aliyun-cs-readonly" --- apiVersion: agentidentity.alibabacloud.com/v1alpha1 kind: AgentRoleBinding metadata: name: my-agent-get-aliyun-sts namespace: <YOUR_NAMESPACE> spec: agentRoleRef: apiGroup: agentidentity.alibabacloud.com kind: AgentRole name: get-aliyun-sts subjects: - authorizationType: "Agent" agentAuthorizationConfiguration: agentName: my-agent -
Save the following content as
security-profile-sts.yamland run the kubectl apply -f command to create a SecurityProfile and configure a token transformation rule.apiVersion: agents.kruise.io/v1alpha1 kind: SecurityProfile metadata: name: aliyun-sts-injection namespace: <YOUR_NAMESPACE> spec: selector: matchLabels: security.agents.kruise.io/agent-name: my-agent rules: - name: inject-aliyun-sts match: - domains: - "*.aliyuncs.com" actions: tokenTransformation: type: AliyunSTS credentialRef: kind: CredentialProvider name: aliyun-cs-readonlyFor a description of key fields, see tokenTransformation fields.
-
Save the following content as
sandboxset-sts.yamland run thekubectl apply -fcommand to create a SandboxSet and configure fake AK/SK in the environment variables. (The Alibaba Cloud SDK in the Sandbox uses these fake credentials to make requests, and the gateway replaces them with real credentials when forwarding.)apiVersion: agents.kruise.io/v1alpha1 kind: SandboxSet metadata: name: sts-test namespace: <YOUR_NAMESPACE> spec: replicas: 2 runtimes: - name: csi - name: agent-runtime template: metadata: annotations: network.alibabacloud.com/network-policy-mode: enhanced-traffic-policy labels: alibabacloud.com/acs: "true" spec: automountServiceAccountToken: false containers: - name: sandbox image: registry-cn-hangzhou.ack.aliyuncs.com/acs/acs-ephemeraljob-tools-asi:v0.6 # Replace with your business image. env: - name: ALIBABA_CLOUD_ACCESS_KEY_ID value: "FAKE_AK" # Fake AK, automatically replaced by the gateway. - name: ALIBABA_CLOUD_ACCESS_KEY_SECRET value: "FAKE_SK" # Fake SK, automatically replaced by the gateway. - name: ALIBABA_CLOUD_REGION value: "cn-hangzhou" # Replace with your actual region. resources: requests: cpu: "2" memory: 2Gi limits: cpu: "2" memory: 2GiWait for the Pod to be ready, and confirm that the Sandbox is in the
Runningstate:kubectl get sandbox -n <YOUR_NAMESPACE>Expected output:
NAME STATUS AGE CLAIMED sts-test-xxxxx Running 60s false sts-test-yyyyy Running 60s false -
Save the following content as
sandboxclaim-sts.yamland run the kubectl apply -f command to allocate a Sandbox and associate an Agent identity using a SandboxClaim.apiVersion: agents.kruise.io/v1alpha1 kind: SandboxClaim metadata: name: sts-test-claim namespace: <YOUR_NAMESPACE> spec: templateName: sts-test replicas: 1 claimTimeout: 5m ttlAfterCompleted: 15m labels: security.agents.kruise.io/agent-name: my-agent # Associate with the AgentIdentity.Confirm that the
CLAIMEDstatus of one of the Sandboxes changes totrue, and check the token issuance status:CLAIMED_POD=$(kubectl get sandbox -n <YOUR_NAMESPACE> \ -l agents.kruise.io/sandbox-claimed=true,agents.kruise.io/sandbox-template=sts-test \ -o jsonpath='{.items[0].metadata.name}') kubectl get sandbox $CLAIMED_POD -n <YOUR_NAMESPACE> -o yaml | grep token-statusThe expected output includes information about the token's expiration time:
security.agents.kruise.io/token-status: '{"accessTokenExpiration":"2026-06-05T04:41:40Z"}' -
Log in to the claimed Sandbox Pod, install the Alibaba Cloud CLI, and use the fake credentials to verify that the STS credential injection is successful.
kubectl exec -it $CLAIMED_POD -n <YOUR_NAMESPACE> -c sandbox -- bashIn the Sandbox, run the following commands:
# 1. Install Alibaba Cloud CLI. /bin/bash -c "$(curl -fsSL https://aliyuncli.alicdn.com/install.sh)" # 2. Configure fake credentials. mkdir -p ~/.aliyun cat > ~/.aliyun/config.json << 'EOF' { "current": "default", "profiles": [{ "name": "default", "mode": "AK", "access_key_id": "FAKE_AK", "access_key_secret": "FAKE_SK", "region_id": "cn-hangzhou", "output_format": "json", "language": "en" }] } EOF # 3. Call the CS API (authorized, expected to succeed). aliyun cs GET /api/v1/clustersA successful response lists the clusters in JSON format, confirming that the gateway transparently replaced the fake credentials with real temporary credentials obtained through STS
AssumeRole.
-
tokenTransformation fields
This section provides a reference for tokenTransformation rule fields, CredentialProvider template variables, and the signature methods supported in Alibaba Cloud STS mode.
CRD fields
actions:
tokenTransformation:
disabled: false # Optional. Temporarily disables the rule.
failStrategy: Block # Optional. Failure strategy: Block (default) or Allow.
type: ApiKey | AliyunSTS # Required. The injection mode.
credentialRef: # Required. The credential source.
kind: CredentialProvider # CredentialProvider or Secret.
name: <name> # The resource name.
namespace: <ns> # Optional. Defaults to the namespace of the SecurityProfile.
# Specific to ApiKey mode (required when type is ApiKey)
apiKey:
when: # Optional. The precondition for injection.
header: Authorization # The request header to check.
pattern: "^Bearer .+" # An RE2 regular expression.
targetHeader: Authorization # The target request header. Defaults to Authorization.
valueTemplate: "Bearer {{ .Token }}" # The value template.
|
Field |
Description |
|
|
Injection mode: |
|
|
Set to |
|
|
Handling policy for credential acquisition or signature failures: |
|
|
Credential source type: |
|
|
The name of the referenced |
|
|
The precondition for injection. Specifies the request header to check and an RE2 regular expression to match. Injection is performed only if the condition is met. |
|
|
The target request header to replace. The default is |
|
|
A value template in Go text/template format. |
CredentialProvider template variables
The policy and secretRef.name fields of CredentialProvider support template variables. These variables reference contextual information about the Sandbox instance identity to dynamically adjust permission scopes or reference different Secrets per instance.
|
Template variable |
Description |
|
|
The name of the AgentIdentity CR that is associated with the sandbox instance identity. This name is specified by the label |
|
|
The value of a specific key in the user-defined metadata associated with the Sandbox instance identity. Replace |
The following example passes an OSS bucket and subpath through the labels of a SandboxClaim to dynamically scope down OSS permissions in the CredentialProvider policy for each Sandbox instance.
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxClaim
metadata:
name: my-claim
namespace: <YOUR_NAMESPACE>
spec:
templateName: my-sandbox-set
replicas: 1
labels:
security.agents.kruise.io/agent-name: my-agent
# The following labels can be referenced in the policy template by using ${ack:agent-identity/metadata/KEY}.
security.agents.kruise.io/oss-bucket-name: my-bucket
security.agents.kruise.io/oss-subpath: user-data{
"Action": ["oss:Get*", "oss:List*"],
"Effect": "Allow",
"Resource": [
"acs:oss:*:*:${ack:agent-identity/metadata/oss-bucket-name}/${ack:agent-identity/metadata/oss-subpath}/*"
]
}
Supported signature methods
The system automatically detects the request signature method, so no manual configuration is required. It supports standard signed requests from Alibaba Cloud SDKs for Go, Java, Python, Node.js, and other languages. If a request does not contain a recognizable Alibaba Cloud signature, the system skips the token transformation action, and the request proceeds as-is or is matched against subsequent rules.
|
Signature version |
Signature algorithm |
Typical SDK version |
Detection method |
|
V3 (ACS3-HMAC-SHA256) |
HMAC-SHA256 |
Alibaba Cloud SDK 2.0 and later (V2 SDK) |
The |
|
V1 RPC (HMAC-SHA1) |
HMAC-SHA1 |
V1 SDK, RPC style |
The query parameters include |
|
V1 ROA (HMAC-SHA1) |
HMAC-SHA1 |
V1 SDK, ROA style |
The |
|
OSS V4 (OSS4-HMAC-SHA256) |
HMAC-SHA256 |
OSS SDK V4 signature |
The |
Limitations
|
Limitation |
Description |
|
The Alibaba Cloud STS mode requires HTTPS traffic management |
Alibaba Cloud SDKs use HTTPS by default. You must configure TLS termination to intercept and rewrite requests. |
|
The Alibaba Cloud STS mode does not support OSS V1 signatures |
The gateway cannot recognize or re-sign requests that use the legacy OSS V1 signature. |
|
The Alibaba Cloud STS mode does not support SLS private signatures |
The SLS service uses a non-standard signature method, which is not currently supported. |
|
Credential replacement applies only to egress traffic |
It only affects requests that are forwarded through the |
|
A single rule supports only one |
To inject different credentials for different domains, create multiple rules. |
|
Maximum length of |
The maximum length is 1,024 characters. |
FAQ
Why is credential injection not working?
Troubleshoot the issue by following these steps:
-
Verify that the Sandbox is associated with the correct
security.agents.kruise.io/agent-namelabel via the SandboxClaim. -
Verify that the
selector.matchLabelsin the SecurityProfile matches the labels of the Sandbox Pod. -
Verify that the
AgentRoleandAgentRoleBindinghave been correctly configured to grant access to the correspondingCredentialProvider. -
In Alibaba Cloud STS mode, make sure that HTTPS traffic control is enabled and that
includeHostsincludes the target domain (such as*.aliyuncs.com). -
Check the logs of the
traffic-extensioncomponent for any errors.kubectl logs -l app.kubernetes.io/name=traffic-extension -n sandbox-traffic-system
Why do requests return a SignatureDoesNotMatch error?
This can happen for the following reasons:
-
The request uses an unsupported signature method, such as OSS V1 or an SLS private signature. Check whether the format of the
Authorizationheader is in the list of supported signature methods for the Alibaba Cloud STS mode. -
You have configured
type: ApiKeybut the target is an Alibaba Cloud API. The ApiKey mode only replaces the header and does not re-sign the request. You should usetype: AliyunSTSinstead.