Agent Sandbox security best practices
ACS Agent Sandbox secures agent workloads across four dimensions: network isolation, storage security, credential and identity management, and runtime security. Use these best practices to build defense in depth.
Security capabilities
ACS Agent Sandbox provides security capabilities that span network isolation, storage security, and credential and identity management.
Security domain | Capabilities |
Compute isolation | Agent Sandbox isolation |
Network isolation | Dedicated vSwitch + enterprise security group + L4 TrafficPolicy + L7 SecurityProfile |
Storage security | CSI dynamic mounting + temporary token authentication + ReadOnly + subPath isolation |
Credential management | AgentIdentity + ServiceAccount disabling + KMS Secrets Manager |
Access control | AgentRole/AgentRoleBinding + RBAC |
Observability | Egress traffic audit webhook + Prometheus monitoring integration |
Runtime security | Agent Security Center + Agentic SOC (SIEM+SOAR) |
Network security capabilities and best practices
Network security capabilities
Network partition trust model
Cluster workloads are divided into three network partitions by trust level. Isolate sandboxes with a dedicated vSwitch and a dedicated enterprise security group. For details about the network partition architecture, see Agent Sandbox network planning and scaling.
Network partition | Trust level | Typical components | vSwitch | Security group |
Managed system components | High | Kube API Server, CCM, ack-agent-sandbox-controller, ack-agent-identity | Control plane vSwitch | Control plane security group |
Unmanaged system components | Medium | ack-sandbox-manager | Control plane vSwitch | Control plane security group |
Sandbox compute | Untrusted | Sandbox pod | Dedicated vSwitch | Dedicated enterprise security group |
ACS Agent Sandbox supports three network policy modes with progressively enhanced security capabilities:
Mode | Value | Capability | Dependent add-ons |
Basic network policy |
| Supports only native Kubernetes NetworkPolicy. | — |
Traffic policy |
| L4 ingress and egress traffic management (TrafficPolicy CRD). | Poseidon |
Enhanced traffic policy |
| L4 (TrafficPolicy) and L7 egress management (SecurityProfile CRD), with automatic injection of the traffic-proxy sidecar. | ack-sandbox-manager (≥0.6.1) + Poseidon |
Dedicated vSwitch (subnet isolation)
ACS Agent Sandbox lets you specify a dedicated vSwitch for sandbox pods, physically isolating sandbox traffic from the cluster control plane and application pods at the subnet level.
annotations:
network.alibabacloud.com/vswitch-ids: "vsw-****"Enterprise security group (VPC boundary protection)
Configure a dedicated enterprise security group for sandbox pods to provide coarse-grained boundary protection at the VPC level.
annotations:
network.alibabacloud.com/security-group-ids: "sg-****"TrafficPolicy and GlobalTrafficPolicy (L4 micro-segmentation)
Powered by the Poseidon add-on, TrafficPolicy provides pod-level L4 ingress and egress traffic control, with support for matching by IP CIDR block, Service, and fully qualified domain name (FQDN). ACS provides two resources that share the same spec but differ in scope:
Property | TrafficPolicy | GlobalTrafficPolicy |
Scope | Namespace-level | Cluster-level |
| All pods in the current namespace | All pods in the cluster |
Typical scenario | Application-level fine-grained rules | Cluster-wide security baseline |
API group |
| Same as left |
Policy execution order: Policies are evaluated based on a priority from 1 to 1000 (lower values are higher priority). Policies with the same priority are evaluated in the order they are defined. The first matching rule terminates the evaluation. For any pod selected by a policy, all traffic not explicitly allowed is denied by default. Place specific rules before general, catch-all rules.
FQDN matching limitations: Wildcard domains are not supported. Dynamic DNS resolution introduces delays. If multiple domains resolve to the same IP address, you cannot create distinct allow and deny rules for them. We recommend using FQDN matching for internal services only. For public endpoints or wildcard domains, use SecurityProfile L7 domain matching instead.
SecurityProfile (enhanced L7 egress control)
SecurityProfile is an L7 egress traffic control feature exclusive to ACS Agent Sandbox. It transparently intercepts all outgoing requests through an automatically injected traffic-proxy sidecar and evaluates them against security policies at the egress-gateway layer.
Architecture overview:
Core components (deployed in the sandbox-traffic-system namespace):
Component | Role |
gateway-controller | Manages and distributes the configurations of traffic-proxy and egress-gateway. |
egress-gateway | Receives and forwards all egress traffic from sandboxes in the cluster. |
traffic-extension | Enforces egress traffic control policies, such as traffic interception and token injection. |
traffic-proxy (sidecar) | Injected into sandbox pods. Transparently intercepts egress traffic and forwards it to egress-gateway. |
Matching dimensions supported by SecurityProfile:
Dimension | Field | Description |
Domain |
| Supports wildcards such as |
URL path |
| Supports Prefix / Exact / Regex (RE2). |
HTTP method |
| GET, POST, PUT, DELETE, and PATCH. |
Port |
| An array, for example, |
Request header |
| Supports Exact / Prefix / Regex. |
Query parameter |
| Supports Exact / Prefix / Regex. |
Rule matching logic:
Multiple fields in the same
matchentry are combined with the AND operator.Multiple
matchentries are combined with the OR operator.Rules are evaluated in order. Block and Bypass are terminal actions: when a rule with either action matches, evaluation stops.
HTTPS traffic control is supported. After you enable Transport Layer Security (TLS) termination, egress-gateway terminates TLS for HTTPS requests to specified domains and applies SecurityProfile rules to the decrypted traffic. This process is fully transparent to sandbox applications.
The following table compares the typical capabilities of TrafficPolicy and SecurityProfile.
Matching dimension | TrafficPolicy | SecurityProfile |
IP CIDR | Supported | — |
Service (namespace + name) | Supported | — |
FQDN domain | Supported (exact match only) | Supported (exact match and wildcards) |
Ingress control | Supported | — |
Port | Supported | Supported |
URL path | — | Supported (Prefix / Exact / Regex) |
HTTP method | — | Supported (GET/POST/PUT/DELETE...) |
Request header | — | Supported (Exact / Prefix / Regex) |
Query parameter | — | Supported (Exact / Prefix / Regex) |
Network security best practices
Practice 1: Use enhanced-traffic-policy mode
TrafficPolicy | SecurityProfile | |
Role | L4: Determines connectivity based on IP address, port, and protocol. | L7: Determines API accessibility based on domain, path, method, and headers. |
Working layer | L4 (TCP layer) | L7 (HTTP/HTTPS layer) |
Control direction | Ingress and egress | Egress only |
Theenhanced-traffic-policymode includes both L4 (TrafficPolicy) and L7 (SecurityProfile) capabilities. Select this mode to use both policy types without enabling thetraffic-policymode separately.
ACS Agent Sandbox uses the network.alibabacloud.com/network-policy-mode annotation to specify the network policy mode:
network.alibabacloud.com/network-policy-mode: enhanced-traffic-policyThe following is a complete configuration example:
apiVersion: agents.kruise.io/v1alpha1
kind: Sandbox
metadata:
name: sample
namespace: default
spec:
runtimes:
- name: agent-runtime
template:
metadata:
labels:
agent: sample
alibabacloud.com/compute-class: agent-sandbox
annotations:
network.alibabacloud.com/network-policy-mode: enhanced-traffic-policy
spec:
containers:
- name: sandbox
image: registry-cn-zhangjiakou.ack.aliyuncs.com/acs/code-interpreter:v1.6 # Replace with the region where your cluster is located.
command: ["/bin/sleep", "infinity"]Practice 2: Deny internal network access by default
Sandboxes run untrusted, AI-generated code, so you must assume that the code is vulnerable to prompt injection attacks. Configure a TrafficPolicy to deny access to all internal network segments by default:
apiVersion: network.alibabacloud.com/v1alpha1
kind: TrafficPolicy
metadata:
name: agent-internet-only-policy
namespace: default
spec:
priority: 100
selector:
matchLabels:
app: agent
egress:
rules:
# Allow DNS
- action: allow
to:
- service:
namespace: kube-system
name: kube-dns
# Deny access to private networks
- action: deny
to:
- cidr: 10.0.0.0/8
- action: deny
to:
- cidr: 172.16.0.0/12
- action: deny
to:
- cidr: 192.168.0.0/16Practice 3: Restrict ECS metadata service access
Code within the sandbox can access the Alibaba Cloud ECS metadata endpoint (100.100.100.200) to obtain temporary credentials for the instance role, which can lead to credential leakage. Blocking this endpoint is one of the most important security configurations.
- action: deny
to:
- cidr: 100.100.100.200/32Use a high-priority GlobalTrafficPolicy (priority 1) to block access to the metadata service across the entire cluster. No application-level policy can then bypass this rule (see Practice 6).
Practice 4: Allowlist essential external access
If the sandbox needs to access external resources, such as an OSS endpoint, use an FQDN or CIDR allowlist to grant precise access:
egress:
rules:
# Allow DNS
- action: allow
to:
- service:
namespace: kube-system
name: kube-dns
# Allow a specific OSS endpoint
- action: allow
to:
- fqdn: your-bucket.oss-cn-hangzhou-internal.aliyuncs.com
# Deny the sandbox access to sandbox-gateway and sandbox-manager to prevent pivoting to other sandboxes
- action: deny
to:
- service:
name: sandbox-gateway
namespace: sandbox-system
- service:
name: sandbox-manager
namespace: sandbox-system
# Allow public network access as needed (only if the Agent requires internet access)
- action: allow
to:
- cidr: 0.0.0.0/0FQDN matching has limitations, including resolution delays and ambiguity when multiple domains share the same IP address. For public endpoints or wildcard domains, use SecurityProfile L7 domain matching instead (see Practice 11).
Practice 5: Restrict ingress traffic to the control plane
A sandbox pod should not accept inbound connections from arbitrary sources. Allow traffic from the vSwitch CIDR blocks of control plane components first, because this avoids the delay of resolving pod IP addresses. Use Service matching as a secondary method and ensure all necessary webhook components are included:
# Ingress rules
- action: allow
from:
- service:
namespace: sandbox-system
name: sandbox-gateway
- service:
namespace: sandbox-system
name: sandbox-manager
- service:
namespace: sandbox-system
name: sandbox-controller-manager-webhook-service
- action: deny
from:
- cidr: 0.0.0.0/0To find the vSwitch CIDR for the control plane and unmanaged components, navigate to Cluster Information > Basic Information > Network > Control Plane vSwitch.
Practice 6: Use GlobalTrafficPolicy for a security baseline
Use GlobalTrafficPolicy to apply baseline rules that no sandbox can bypass. This approach avoids redundant namespace-level configurations and prevents gaps caused by missing configurations.
High-priority GlobalTrafficPolicy (priority 1): Enforce a hard block on the metadata service. Application-level policies cannot override this rule.
Low-priority GlobalTrafficPolicy (priority 1000): Provide a catch-all denial for internal network segments and cross-sandbox traffic.
Application-level TrafficPolicy (priority 50–200): Define fine-grained allow rules for specific agents.
apiVersion: network.alibabacloud.com/v1alpha1
kind: GlobalTrafficPolicy
metadata:
name: global-metadata-hard-deny
spec:
priority: 1 # Highest priority, cannot be overridden
selector: {} # All pods in the cluster
egress:
rules:
- action: deny
to:
- cidr: 100.100.100.200/32
---
apiVersion: network.alibabacloud.com/v1alpha1
kind: GlobalTrafficPolicy
metadata:
name: global-sandbox-baseline
spec:
priority: 1000 # Low-priority catch-all
selector: {}
egress:
rules:
- action: deny
to:
- cidr: 10.0.0.0/8
- cidr: 172.16.0.0/12
- cidr: 192.168.0.0/16
- cidr: 100.64.0.0/10
- action: allow
to:
- cidr: 0.0.0.0/0
ingress:
rules:
# Deny traffic between sandbox network segments to prevent lateral movement.
- action: deny
from:
- cidr: 10.8.0.0/16 # Replace with your actual sandbox vSwitch CIDR block.
- action: allow
from:
- cidr: 0.0.0.0/0Practice 7: Allow system components in network policies
Before configuring any deny-all policies, create allow rules for the following system components. Otherwise, sandbox functions break: DNS resolution fails, credential injection fails, policies are not delivered, and you cannot connect to the sandbox.
System component | Direction | Port/Protocol | Impact of misconfiguration |
CoreDNS / kube-dns | Egress | TCP/53, UDP/53 | All domain access fails, including access to SDKs and OSS endpoints. |
Poseidon | Egress | TCP/9082 | TrafficPolicy rules fail to take effect or are delayed. |
ack-sandbox-manager / sandbox-gateway | Ingress | TCP/49983, 49999 | Cannot connect to the sandbox; exec commands fail. |
ack-agent-sandbox-controller | Ingress | TCP/49983 | Sandbox creation or management fails. |
ack-agent-identity | Egress | TCP/8443 | Credential injection fails (requests are rejected if failStrategy=Block). |
enhanced-traffic-policy gateway | Egress | TCP/15008, 15012 | SecurityProfile egress control fails or requests are blocked. |
Monitoring (Prometheus/node-exporter/Ingress) | Ingress | TCP/9090, 9100, 10254 | Monitoring data is missing. |
Health probe | Ingress | ICMP | Health checks fail, causing pods to be misidentified as unhealthy. |
Practice 8: Configure the enterprise security group
A security group provides coarse-grained boundary protection at the VPC and elastic network interface (ENI) layer. A security group and TrafficPolicy apply together: traffic must pass both. TrafficPolicy provides fine-grained, pod-level control.
Configure a dedicated enterprise security group for the sandbox. By default, this provides intra-group isolation (instances within the same group cannot communicate with each other), which prevents lateral movement without requiring extra configuration.
A single security group supports a maximum of 65,536 ENIs. Keep IP address utilization at or below 80% (approximately 52,000 ENIs). Plan to scale out before you approach this limit (see Practice 10).
For details about security group rules, see Reuse or create a sandbox security group.
Practice 9: Isolate the control plane with a vSwitch
Create a dedicated vSwitch (for example, 10.10.0.0/16) for the sandbox and do not reuse the control plane vSwitch. Never add the sandbox vSwitch to the list of cluster control plane vSwitches, as network isolation policies may disrupt control plane services.
Practice 10: Update policies on network scaling
An enterprise security group has a limit of 65,536 ENIs. When you approach this limit or the vSwitch's IP addresses are exhausted, create a new vSwitch and security group. During scaling, perform the following steps:
Add a NAT SNAT entry for the new vSwitch. Otherwise, the new network segment will not have public network access.
Add inbound rules to the destination security group to allow traffic from the new vSwitch CIDR block for required services (for example, CoreDNS on TCP/UDP 53 and Poseidon on TCP/9082).
Verify that existing TrafficPolicy and GlobalTrafficPolicy rules cover the new network segment.
Configure pods to use the new vSwitch and security group. Sandboxes that are already allocated must be recreated for the changes to take effect.
After scaling, run the following commands to verify the configuration: hostname -i (to check if the IP is in the new CIDR block), curl https://httpbin.org/ip (to verify that SNAT is working), and getent hosts kubernetes.default.svc.cluster.local (to verify that DNS is working).
Practice 11: Use SecurityProfile for L7 egress control
SecurityProfile provides more granular egress control than L4 TrafficPolicy. Configure it for the following use cases:
Scenario A: Allowlist mode (recommended for production environments)
Allow the sandbox to access only known-safe domains and deny all other requests:
apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
name: allowlist-only
spec:
selector:
matchLabels:
alibabacloud.com/compute-class: agent-sandbox
rules:
# Allow known-safe domains
- name: allow-aliyuncs
match:
- domains: ["*.aliyuncs.com"]
actions:
bypass: true
- name: allow-llm-provider
match:
- domains: ["dashscope.aliyuncs.com", "api.openai.com"]
actions:
bypass: true
# Catch-all rule to deny all other domains
- name: deny-all
match:
- domains: ["*"]
actions:
block:
statusCode: 403
body: '{"error":"access denied: domain not in allowlist"}'Scenario B: Block management paths to prevent server-side request forgery (SSRF)
Prevent an agent from accessing management interfaces, even if the domain is on the allowlist:
rules:
- name: deny-management-paths
match:
- domains: ["*"]
paths:
- type: Prefix
value: /admin
- type: Prefix
value: /console
- type: Prefix
value: /dashboard
- type: Prefix
value: /manage
- type: Regex
value: "^/internal/v[0-9]+/.*"
actions:
block:
statusCode: 403
body: '{"error":"management paths are blocked"}'Scenario C: Read-only mode (restrict HTTP write operations)
For agents that only need to read data, block all write methods:
rules:
- name: read-only-mode
match:
- domains: ["*"]
paths:
- type: Prefix
value: /
methods: ["POST", "PUT", "DELETE", "PATCH"]
actions:
block:
statusCode: 405
body: '{"error":"write operations are not allowed in read-only mode"}'Scenario D: Block non-standard ports to prevent security audit bypass
rules:
- name: deny-non-standard-ports
match:
- domains: ["*"]
ports: [8080, 8443, 9090, 3000, 6379, 27017]
actions:
block:
statusCode: 403
body: '{"error":"access to non-standard ports is blocked"}'Practice 12: Enable HTTPS traffic control
For scenarios that require control over HTTPS egress traffic, such as calls to Alibaba Cloud APIs or third-party LLM services, enable TLS termination:
# ack-sandbox-manager add-on configuration
enhancedTrafficManagement:
egressGateway:
tlsTermination:
includeHosts:
- "*.aliyuncs.com" # Alibaba Cloud APIs
- "*.openai.com" # OpenAI
- "api.anthropic.com" # Anthropic
excludeHosts:
- "*.cluster.local" # Exclude internal cluster communicationWhen enabled, the system automatically injects the Gateway CA certificate into sandbox pods and configures environment variables such as SSL_CERT_FILE, NODE_EXTRA_CA_CERTS, REQUESTS_CA_BUNDLE, and CURL_CA_BUNDLE. This process is transparent to the application.
If you enable TLS termination for a domain but a sandbox pod is not configured with the enhanced-traffic-policy annotation and therefore does not have the CA certificate injected, HTTPS requests from that sandbox will fail due to a TLS handshake error.Practice 13: Enable an audit webhook for event tracking
SecurityProfile supports an audit webhook, which sends an HTTP notification to an external service when a rule is matched. This is useful for security auditing, anomaly detection, and event alerting. Auditing is a non-terminal action and does not affect request processing.
apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
name: audited-policy
spec:
selector:
matchLabels:
security.agents.kruise.io/agent-name: my-agent
audit:
- name: central-audit
when: 'result == "blocked"' # Audit only when a request is blocked
webhook:
url: "https://audit.internal.company.com/events"
timeout: 5s
request:
method: POST
headers:
- name: Authorization
value: "Bearer <audit-service-token>"
body:
json:
event: "request_blocked"
result: "{{ .Result }}"
pod: "{{ .Pod.Namespace }}/{{ .Pod.Name }}"
rule: "{{ .Rule.Name }}"
host: "{{ .Request.Host }}"
path: "{{ .Request.Path }}"
method: "{{ .Request.Method }}"
rules:
- name: deny-admin
match:
- domains: ["*"]
paths:
- type: Prefix
value: /admin
actions:
block:
statusCode: 403
body: '{"error":"admin path is blocked"}'CEL expression variables (for the when field):
Variable | Description |
| Processing result: |
| The target domain of the request. |
| The HTTP method. |
| The request path. |
| Information about the source sandbox pod. |
| The name of the matched SecurityProfile. |
| The name of the matched rule. |
Practice 14: Separate control and data plane traffic
In the default configuration, both control plane (api.{domain}) and data plane (*.{domain}) traffic are routed to sandbox-manager. A control plane failure can therefore disrupt application data traffic. If you separate them, data plane traffic goes through sandbox-gateway instead, which isolates faults.
Prerequisites: ack-sandbox-manager v0.5.2 or later and at least one sandbox-gateway replica. The control plane security group must allow inbound traffic on TCP/7788, and TrafficPolicy must allow inbound traffic from sandbox-gateway.
To switch: On the Component and Add-ons page, navigate to ack-sandbox-manager > Configuration and change
dataplaneServicetosandbox-gateway. Perform this operation during off-peak hours. The change can be rolled back if necessary.
Practice 15: Enable SandboxGateway ingress authentication
Relying solely on TrafficPolicy to restrict source IP addresses is insufficient. Add token-based authentication at sandbox-gateway, which supports two methods. Use JWT-based dynamic tokens.
Dimension | Static access token (v0.6.6 and later) | JWT-based dynamic token (v0.6.8 and later, recommended) |
Request header |
|
|
Token format | Random UUID | Asymmetrically signed Compact JWT |
Issuer | sandbox-manager | The |
Validation method | Constant-time string comparison | Local validation of JWT signature, standard claims, and sandbox ID/UID binding. |
Validity period | Same as the sandbox lifecycle; static. | Controlled by issuance parameters; can be reissued upon expiration. |
Leakage replay window | Persists until the sandbox is destroyed. | Limited to the JWT validity period. |
Persistence | Written to the sandbox CR annotation | Not written to the CR; returned only in the creation response. |
Token retrieval field | The | The |
Validation failure response | HTTP | HTTP |
JWT-based dynamic tokens are recommended because a static token is a credential for the data plane and envd. It is stored in plaintext in the CR annotation, and if leaked it can be replayed until the sandbox is destroyed. In contrast, a JWT is a dedicated, proxy-only credential for the data plane. It is asymmetrically signed, bound to a specific sandbox ID/UID, and can be reissued. The exposure window from a leak is limited to the JWT's validity period, and the token is not persisted to the CR. This makes JWTs well-suited when you need time-limited access, replay protection, and multi-tenant isolation.
To enable this feature, see Separate control and data planes in Agent Sandbox.
Storage security capabilities and best practices
Storage capabilities
Capability | Description |
CSI dynamic mounting | The CSI plugin is injected as a sidecar to support dynamic mounting of Object Storage Service (OSS) volumes while the sandbox is running. This requires both the |
Agent Identity authentication | The |
Multi-volume mounting and subPath isolation | Mount multiple volumes by using |
Read-only mount | A read-only mount prevents the sandbox from tampering with shared data. |
This feature uses a two-layer permission model:
Layer 1: Resource Access Management (RAM) role (maximum permission boundary). The RAM role is created in the RAM console. It defines the maximum scope of buckets that a sandbox can access and is bound to an OIDC provider for RAM Roles for Service Accounts (RRSA).
Layer 2: CredentialProvider policy (effective permissions). A
CredentialProvidercustom resource (CR) within the cluster defines this policy, which must be a subset of the Layer 1 permissions. It supports template functions to dynamically narrow permissions based on the bucket and subPath that each sandbox declares.The final permissions are the intersection of the RAM role and the CredentialProvider policy, granting access only to the bucket and subPath that a specific sandbox declares.
Storage security best practices
Practice 16: Use read-only mounts by default
Unless write access is explicitly required, always mount shared storage volumes as read-only.
# SandboxClaim method
dynamicVolumesMount:
- pvName: oss-pv-sandbox-system
mountPath: "/data/readonly"
subPath: "tenant-a/datasets"
readOnly: true
attributes:
credentialProviderName: "oss-ro"Practice 17: Use subPath for tenant isolation
When different tenants mount the same PersistentVolume (PV), use subPath combined with a separate CredentialProvider to isolate each tenant's access to its own data subdirectory, so that tenants cannot see each other's data.
# Tenant A (read-only)
metadata = {
"e2b.agents.kruise.io/csi-volume-config": json.dumps([
{"pvName": "oss-pv-sandbox-system", "mountPath": "/data",
"subPath": "tenants/tenant-a", "attributes": {"credentialProviderName": "oss-ro"}}
]),
"security.agents.kruise.io/agent-name": "my-storage-agent"
}Practice 18: Use Agent Identity and template functions
The policy field of the CredentialProvider supports dedicated template functions. The sandbox-controller automatically populates these functions based on the mount configuration of each sandbox instance, eliminating the need to create a separate CredentialProvider for each subPath.
Template function | Purpose |
| Restricts the Resource to the subPath level for object-level operations, such as GetObject and PutObject. |
| Restricts the Resource to the bucket level for operations such as ListObjects. |
| Generates an |
Read-only CredentialProvider:
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
name: oss-ro
namespace: <YOUR-NAMESPACE>
spec:
type: RAM
ram:
source:
provider: RRSA
rrsa:
roleName: <YOUR-RAM-ROLE-NAME>
tokenValidity: 1h
policy: |
{
"Statement": [
{
"Action": ["oss:GetObject"],
"Effect": "Allow",
"Resource": {{ build_policy_oss_resource() }}
},
{
"Action": ["oss:ListObjects"],
"Effect": "Allow",
"Resource": {{ build_policy_oss_resource(limit_sub_path=false) }},
"Condition": {
"StringLike": { "oss:Prefix": {{ build_policy_oss_prefix_condition() }} }
}
}
],
"Version": "1"
}ListObjects is a bucket-level operation. You must use the oss:Prefix condition to restrict access to a subPath. Otherwise, the sandbox can list the entire bucket. For read and write access, use oss-rw instead, which includes operations such as PutObject and DeleteObject.
Authorization (AgentRole + AgentRoleBinding):
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRole
metadata:
name: oss-storage-role
namespace: <YOUR-NAMESPACE>
spec:
rules:
- effect: Allow
action: "GetResourceCredential"
resource: "CredentialProvider/oss-ro"
- effect: Allow
action: "GetResourceCredential"
resource: "CredentialProvider/oss-rw"
---
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRoleBinding
metadata:
name: my-agent-oss-binding
namespace: <YOUR-NAMESPACE>
spec:
agentRoleRef:
apiGroup: agentidentity.alibabacloud.com
kind: AgentRole
name: oss-storage-role
subjects:
- authorizationType: "Agent"
agentAuthorizationConfiguration:
agentName: my-storage-agentFor more information about template configurations, see Mount OSS storage for an Agent Sandbox.
Practice 19: Use Agent Identity for PVs
With the Agent Identity method, a PersistentVolume does not require nodePublishSecretRef or a Secret.
apiVersion: v1
kind: PersistentVolume
metadata:
name: oss-pv-sandbox-system
labels:
alicloud-pvname: oss-pv-sandbox-system
spec:
accessModes: [ReadWriteMany]
capacity:
storage: 50Gi
csi:
driver: ossplugin.csi.alibabacloud.com
volumeAttributes:
authType: agent-identity # Fixed value
bucket: <YOUR-BUCKET-NAME>
url: https://oss-cn-hangzhou-internal.aliyuncs.com # HTTPS internal endpoint
path: /
otherOpts: "-o sigv4 -o region=cn-hangzhou -o umask=022 -o allow_other" # Must include sigv4 + region
volumeHandle: oss-pv-sandbox-system # Must match the PV name
persistentVolumeReclaimPolicy: Retain
storageClassName: test
volumeMode: FilesystemotherOptsmust include-o sigv4and-o region=<your_region>.A PV's
volumeAttributescannot be modified after creation, so you must delete and recreate the PV to change the authentication method.
Practice 20: SandboxSet and mount settings
SandboxSet enables two runtimes:
csiandagent-runtime. ThednsPolicymust beClusterFirst. Add the annotationnetwork.alibabacloud.com/wait-clusterip-ready: "*".When mounting, use
attributes.credentialProviderNameto specify the CredentialProvider andsecurity.agents.kruise.io/agent-nameto associate the AgentIdentity. The two names must match exactly, and matching is case-sensitive.Mount multiple subPaths on a single sandbox, referencing
oss-rofor read-only paths andoss-rwfor writable paths.
Practice 21: Use an HTTPS endpoint to access OSS
The PV url uses an HTTPS internal endpoint to encrypt storage traffic in transit:
url: "https://oss-cn-hangzhou-internal.aliyuncs.com"Practice 22: CSI sidecar security trade-offs
CSI dynamic mounting requires a privileged container and a hostPath (/var/run/csi), which breaks the standard container security boundary.
Enable the CSI runtime only when dynamic storage mounting is necessary.
If you only need static data, consider building it into the image or pre-loading it with an init container.
When you enable CSI, use TrafficPolicy and security group configurations as compensating controls.
This follows the shared responsibility model: Alibaba Cloud secures the platform, but you are responsible for the additional risks associated with using privileged containers.
Network access for OSS mounting: When you mount an OSS bucket by using Agent Identity, the network policy must allow traffic to CredentialProvider (ack-agent-identity/credential-provider, outbound TCP port 8443 in the security group), CoreDNS (port 53), and the OSS endpoint (HTTPS). Verification: telnet credential-provider.ack-agent-identity.svc 8443.
Credential and identity management
Credential security on Alibaba Cloud
API key multi-tenant authentication
sandbox-manager provides built-in API key authentication with team-level isolation:
Each team maps to a Kubernetes Namespace.
An API key can only manage sandboxes within its associated team.
The admin key cannot be deleted.
Disabled ServiceAccount tokens
By default, the SandboxSet template sets automountServiceAccountToken: false, preventing the sandbox from accessing Kubernetes API credentials.
Environment variable cleanup
You can clear Kubernetes-injected service environment variables, such as KUBERNETES_SERVICE_HOST, to prevent leaking cluster information.
Egress credential injection (Agent Identity framework)
ACS Agent Sandbox injects egress credentials by design: the sandbox holds only placeholder credentials. Real credentials are dynamically substituted at the egress-gateway layer, so the sandbox never sees the actual secret keys.
Five CRDs collaborate to implement credential injection, and two injection modes are available:
CRD | API group | Description |
|
| Defines an agent identity, associated with a sandbox via a label. |
|
| Defines the source of a real credential, such as a Kubernetes Secret or an RRSA RAM role. |
|
| Defines authorization rules that specify which |
|
| Binds an |
|
| Defines |
Mode | Use case | Description |
API key injection | Third-party LLM services, such as OpenAI and Qwen. | Replaces the placeholder token in the request header with the real API key. |
Alibaba Cloud STS credential injection | Calling Alibaba Cloud OpenAPI. | Replaces the AccessKey ID, AccessKey secret, and STS token, and recalculates the request signature. |
Credential and identity best practices
Practice 23: Disable automatic ServiceAccount token mounting
Disabling automatic ServiceAccount token mounting is the most critical credential security configuration. You must ensure that the pod template of every SandboxSet includes the following settings:
spec:
automountServiceAccountToken: false
enableServiceLinks: falseautomountServiceAccountToken: false: Prevents the ServiceAccount token from being mounted.enableServiceLinks: false: Prevents the injection of environment variables related to services.
If you do not configure these settings, code within the sandbox can:
Read
/var/run/secrets/kubernetes.io/serviceaccount/tokento obtain a Kubernetes API token.Discover the Kubernetes API Server address through environment variables.
Directly call the Kubernetes API to manipulate cluster resources.
Practice 24: Clean up Kubernetes environment variables
Explicitly override the environment variables that Kubernetes automatically injects to prevent leaking cluster topology information:
spec:
containers:
- name: sandbox
env:
- name: KUBERNETES_SERVICE_HOST
value: ""
- name: KUBERNETES_SERVICE_PORT
value: ""
- name: KUBERNETES_SERVICE_PORT_HTTPS
value: ""Practice 25: Use credential injection
Never place real credentials inside a sandbox. Use the Agent Identity egress credential injection framework, which allows the sandbox to hold only placeholder credentials while real credentials are substituted at the gateway layer.
Example of API key injection for an LLM API key:
# 1. Create an agent identity.
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentIdentity
metadata:
name: my-agent
namespace: tenant-a
spec:
description: "AI Agent identity for the production environment"
---
# 2. Store the real API Key in a Kubernetes Secret. This is managed at the cluster level and is not visible to the sandbox.
apiVersion: v1
kind: Secret
metadata:
name: llm-api-key
namespace: tenant-a
type: Opaque
stringData:
apiKey: "sk-xxxxxxxxxxxxxxxx" # Real API Key
---
# 3. Create a CredentialProvider that references the Secret.
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
name: llm-api-key
namespace: tenant-a
spec:
type: APIKey
apiKey:
source:
provider: Kubernetes
kubernetes:
secretRef:
name: llm-api-key
keyName: apiKey
---
# 4. Grant permissions by using an AgentRole and AgentRoleBinding.
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRole
metadata:
name: get-llm-key
namespace: tenant-a
spec:
rules:
- effect: Allow
action: "GetResourceCredential"
resource: "CredentialProvider/llm-api-key"
---
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: AgentRoleBinding
metadata:
name: my-agent-get-llm-key
namespace: tenant-a
spec:
agentRoleRef:
apiGroup: agentidentity.alibabacloud.com
kind: AgentRole
name: get-llm-key
subjects:
- authorizationType: "Agent"
agentAuthorizationConfiguration:
agentName: my-agent
---
# 5. Define a substitution rule in a SecurityProfile.
apiVersion: agents.kruise.io/v1alpha1
kind: SecurityProfile
metadata:
name: inject-llm-key
namespace: tenant-a
spec:
selector:
matchLabels:
security.agents.kruise.io/agent-name: my-agent
rules:
- name: inject-openai-key
match:
- domains: ["api.openai.com", "dashscope.aliyuncs.com"]
actions:
tokenTransformation:
type: ApiKey
credentialRef:
kind: CredentialProvider
name: llm-api-key
apiKey:
when:
header: Authorization
pattern: "^Bearer .+" # Replaces the token only if the header contains a Bearer token.
targetHeader: Authorization
valueTemplate: "Bearer {{ .Token }}"The code inside the sandbox can use any placeholder token:
import openai
client = openai.OpenAI(api_key="fake-token") # Placeholder credential. The gateway replaces it with the real API Key.Example of Alibaba Cloud STS credential injection for calling Alibaba Cloud APIs:
# Use RRSA in the CredentialProvider to obtain a temporary STS credential.
apiVersion: agentidentity.alibabacloud.com/v1alpha1
kind: CredentialProvider
metadata:
name: aliyun-cs-readonly
namespace: tenant-a
spec:
type: RAM
ram:
source:
provider: RRSA
rrsa:
roleName: ack-agent-identity-sample-role
# The policy limits the permission scope of the issued STS token, which must be a subset of the role's permissions.
policy: |
{
"Statement": [{
"Action": ["cs:Describe*", "cs:Get*", "cs:List*"],
"Effect": "Allow",
"Resource": ["*"]
}],
"Version": "1"
}Use placeholder AK/SK credentials in the sandbox. The gateway transparently replaces these credentials and recalculates the signature, allowing SDK calls to function normally:
env:
- name: ALIBABA_CLOUD_ACCESS_KEY_ID
value: "FAKE_AK" # Placeholder
- name: ALIBABA_CLOUD_ACCESS_KEY_SECRET
value: "FAKE_SK" # PlaceholderPractice 26: Use template variables for least privilege
The policy and secretRef.name fields of a CredentialProvider support template variables, allowing you to dynamically adjust the permission scope based on the identity of each sandbox instance:
# Pass business parameters through labels in the SandboxClaim.
apiVersion: agents.kruise.io/v1alpha1
kind: SandboxClaim
metadata:
name: user-sandbox
spec:
templateName: my-sandbox-set
replicas: 1
labels:
security.agents.kruise.io/agent-name: my-agent
security.agents.kruise.io/oss-bucket-name: user-bucket-123
security.agents.kruise.io/oss-subpath: user-data/alice// Reference template variables in the CredentialProvider's policy.
{
"Action": ["oss:Get*", "oss:List*"],
"Effect": "Allow",
"Resource": [
"acs:oss:*:*:${ack:agent-identity/metadata/oss-bucket-name}/${ack:agent-identity/metadata/oss-subpath}/*"
]
}This configuration ensures that each sandbox instance receives an STS token with different permissions, implementing the principle of least privilege.
Available template variables:
Template variable | Description |
| The name of the associated |
| A custom value from a label in the |
Practice 27: Set failStrategy to Block
When credential injection fails (for example, a Secret does not exist or the STS quota is exhausted), the failStrategy determines how the request is handled:
actions:
tokenTransformation:
failStrategy: Block # Default. Blocks the request if credential retrieval fails.
# failStrategy: Allow # Dangerous! Allows the original request (with placeholder credentials) to proceed on failure. Use for debugging only.In a production environment, you must use Block (the default value). If set to Allow, a failed injection sends the original request with the placeholder credential (for example, FAKE_AK) to the target service. While this does not leak real credentials, it can expose the sandbox's identity information.
Practice 28: Be aware of STS API quotas
STS mode relies on the AssumeRoleWithOIDC API to obtain temporary credentials. To prevent injection failures from an insufficient quota, apply for a sufficient API call quota in Quota Center based on the expected scale of your sandbox instances.
Practice 29: Manage the API key lifecycle
Save immediately: The plaintext API key is returned only once upon creation and cannot be retrieved again.
Rotate regularly: Establish a key rotation mechanism to delete old keys and create new ones.
Minimize scope: Create an independent key for each integration or agent application instead of sharing a single key.
Monitor usage: Audit key usage with the
lastUsedfield and clean up unused keys in a timely manner.
# Check the last time a key was used.
curl -H "X-API-KEY: $ADMIN_KEY" https://your.domain.com/kruise/api/api-keysPractice 30: Use namespace-level tenant isolation
Use the Team-to-Namespace mapping to achieve tenant isolation:
Assign an independent Kubernetes namespace to each tenant.
A tenant's API key can only manage sandboxes within its own namespace.
Strengthen isolation between namespaces with Kubernetes RBAC and NetworkPolicy.
# Create a namespace for a tenant.
kubectl create ns tenant-security-team
# Create an API Key for the tenant by using the admin key.
curl -X POST -H "X-API-KEY: $ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "security-team-key", "teamName": "tenant-security-team"}' \
https://your.domain.com/kruise/api/api-keysPractice 31: Disable the host network
Ensure that hostNetwork: false (the default value) is specified in the SandboxSet template. This prevents the sandbox from directly accessing the host's network stack:
spec:
hostNetwork: false # Must be set to false.Practice 32: Run containers as a non-root user
Application containers should run as a non-root user to follow the principle of least privilege. Even in the event of a container escape or application vulnerability, a non-root identity significantly reduces the blast radius. Attackers cannot directly read or write privileged sandbox paths, load kernel modules, or abuse root capabilities.
Explicitly declare this in the securityContext of the SandboxSet pod template:
spec:
securityContext:
runAsNonRoot: true # Rejects attempts to run as root (uid 0), validated at startup.
runAsUser: 1000 # Specifies a non-root UID.
runAsGroup: 1000
fsGroup: 1000 # Sets the group ownership of volumes to this GID, ensuring the non-root user can read and write to mounted volumes.
containers:
- name: app
securityContext:
allowPrivilegeEscalation: false # Prevents privilege escalation through setuid.
readOnlyRootFilesystem: true # Makes the root filesystem read-only (configure writable directories as needed).
capabilities:
drop: ["ALL"] # Drops all Linux capabilities.Key points:
runAsNonRoot: trueacts as a hard gate. If an image runs as root by default andrunAsUseris not specified, the pod fails to start (fail-closed). This forces you to detect and fix images that run as root.Without modifying the application image, you can implement this using only the
securityContextandfsGroupfields. If the application code requires write access to a specific path, use an init container (running as root) to pre-create the directory or symbolic link and then usechownto transfer ownership to the application's UID.
Runtime security capabilities and best practices
The network, storage, and credential controls in ACS Agent Sandbox provide baseline, preventive security. However, complete security also requires detective and responsive controls. Alibaba Cloud Security Center offers two core products that complement ACS Agent Sandbox to cover the full cycle from prevention to detection and response:
Product | Role | Relationship with Agent Sandbox |
A cloud-native SIEM and SOAR platform for unified log detection and automated response across multiple clouds. | Ingests cluster audit logs and VPC flow logs to detect anomalous behavior at the sandbox level and orchestrate automated responses. | |
Provides dedicated security baseline checks, vulnerability scanning, and real-time interception of malicious runtime behavior for AI Agents. | Detects AI-specific risks within the Agent application itself, such as prompt injection, privilege escalation, and credential leakage. |
Practice 33: Integrate Agentic SOC
Recommendation: Ingest cluster audit logs and VPC flow logs into Agentic SOC for unified threat detection at the sandbox level.
Procedure:
In the Agentic SOC console, enable log ingestion and select cluster audit logs and VPC flow logs.
Configure alert correlation rules to aggregate multi-source alerts from the same sandbox Pod into a single security incident.
Create a playbook tailored for Agent Sandbox scenarios, such as automatically blocking mining pool IPs or revoking STS credentials.
Practice 34: Enable periodic Agent security baseline scans
Recommendation: Add the Agent applications deployed in ACS Agent Sandbox to Agent Security Center and enable periodic security baseline scans.
Key actions:
Add your AI assets to Agent Security Center.
Ensure that all checks in the OpenClaw security baseline pass.
After making configuration changes, immediately run a manual scan to verify that no new risks have been introduced.
Focus on: Gateway binding address, plaintext passwords, Skill allowlist, and unauthorized access.
Practice 35: Deploy OpenClaw for runtime protection
Recommendation: For Agents in your production environment, install the OpenClaw security plugin to intercept runtime threats, such as prompt injection and malicious command execution.
Prerequisites:
The host has OpenClaw installed and runs Node.js 22 or later.
The AI Security Guardrail service is enabled.
Synergy with ACS Agent Sandbox security capabilities:
Security layer | ACS Agent Sandbox capability | Agent Security Center capability | Synergistic effect |
Network layer |
| OpenClaw malicious URL blocking | Dual filtering: The L7 policy allowlist is applied first, followed by the malicious URL denylist. |
Credential layer |
| Security baseline check: no plaintext passwords. | Provides a dual-layer approach by eliminating hardcoded credentials and performing baseline audits. |
Execution layer | Pod-level compute isolation | Real-time blocking of malicious command execution | Even if code in the sandbox is compromised by injection, malicious commands are blocked in real time. |
Detection layer | Audit webhook records L7 requests | Agentic SOC multi-source correlation analysis | Correlates L7 audits, K8s audits, and VPC flow logs. |
Practice 36: Create playbooks for Agent Sandbox
Recommendation: In Agentic SOC, pre-configure automated playbooks for common Agent Sandbox attack scenarios.
Recommended playbook templates:
Playbook name | Trigger condition | Automated actions |
Sandbox Crypto Mining Response | Crypto-mining process and mining pool connection detected. | Terminate process → Isolate file → Block mining pool IP via Cloud Firewall → Notify |
STS Credentials Abuse Response | Abnormal STS API calls (frequency or scope exceeds a threshold). | Revoke STS credentials → Downgrade AgentRole → Audit and trace → Notify |
Reverse Shell Response | Reverse shell command detected. | Block connection → Terminate process → Create forensic snapshot → Notify |
Data Exfiltration Response | Abnormal, large-scale downloads from OSS detected. | Temporarily suspend CSI mount permissions → Audit access logs → Notify |
Practice 37: Build a defense-in-depth strategy
Recommendation: Combine the capabilities of Alibaba Cloud security products, such as ACS Agent Sandbox, Agentic SOC, Agent Security Center, and AI Security Guardrail, to build defense in depth.
Defense-in-depth layers:
Layer | Typical security capabilities |
ACS Agent Sandbox |
|
Agent Security Center |
|
Agentic SOC |
|
Least privilege checklist
Least privilege for the computing layer
Parameter | Recommended value | Description |
automountServiceAccountToken | false | Blocks access to the Kubernetes API. |
enableServiceLinks | false | Prevents service information disclosure. |
hostNetwork | false | Disables the host network. |
hostPID | false | Prevents access to host processes. |
hostIPC | false | Disables the host IPC namespace. |
securityContext.runAsNonRoot | true | Runs as a non-root user to limit the impact of a container escape. |
securityContext.runAsUser / runAsGroup | Non-zero (for example, 1000) | Specifies a non-root UID/GID. |
securityContext.fsGroup | Matches the UID | Sets group ownership so that non-root users can read and write the mounted volumes.
|
allowPrivilegeEscalation | false | Prevents setuid-based privilege escalation. |
readOnlyRootFilesystem | true | Makes the root filesystem read-only. Configure writable directories as needed. |
capabilities.drop | ["ALL"] | Drops all Linux capabilities. |
Least privilege for the network layer
Parameter | Recommended value | Description |
Network policy mode |
| Enables full L4 and L7 security capabilities. |
Metadata service | Block access to 100.100.100.200/32 | Prevents credential theft. |
Internal network access | Deny internal network access | Prevents lateral movement. |
DNS | Allow only | Allows only DNS resolution. |
External access | Allow specific FQDNs or CIDR blocks as needed | Minimizes the external attack surface. |
L7 egress |
| Allows only known-safe domains. |
Management paths | Block paths such as | Prevents SSRF attacks. |
HTTP write operations | Block POST, PUT, and DELETE methods as needed | Restricts write methods for read-only agents. |
Non-standard ports | Block ports such as 8080, 9090, and 6379 with | Prevents audit bypass. |
Inbound | Allow only control plane component CIDR blocks (see Practice 5) and optionally enable token authentication (see Practice 15) | Prevents external probes. |
Security group | Use a dedicated enterprise security group with intra-group isolation and a port matrix (see Practice 8) | Prevents lateral communication between sandboxes. |
HTTPS control | Enable TLS termination | Ensures encrypted traffic is also controlled by |
Audit | Enable the audit webhook | Makes security incidents traceable. |
Control plane/data plane | Use SandboxGateway to separate the planes | A control plane failure does not affect data communication. |
Drop NET_RAW | Add securityContext configuration | Prevents traffic hijacking, but |
Least privilege for the storage layer
Parameter | Recommended value | Description |
Authentication method | Agent Identity (RRSA + STS) | Avoids storing long-term keys in the sandbox. |
Shared storage mount | readOnly: true | Read-only by default. |
subPath | Configure tenant-specific subdirectories | Ensures data isolation. |
CredentialProvider | Dynamically narrow the scope to a specific bucket or subPath with template functions | Enforces the principle of least privilege for each sandbox. |
PersistentVolume | Set | — |
Storage endpoint | HTTPS internal endpoint | Encrypts data in transit. |
CSI sidecar | Enable only when required | Reduces the attack surface of privileged containers. |
dnsPolicy | ClusterFirst | Resolves the CredentialProvider domain name. |
Least privilege for the credential layer
Parameter | Recommended value | Description |
External API credentials | Agent Identity credential injection | The sandbox holds only placeholder credentials, which the gateway layer replaces. |
Alibaba Cloud API credentials | STS mode + RRSA | Uses temporary credentials with instance-specific permissions. |
CredentialProvider policy | Dynamically narrow permissions with template variables | Enforces least privilege at the sandbox level. |
failStrategy |
| Blocks requests if credential retrieval fails. |
STS quota | Apply for quotas in advance | Prevents injection failures due to insufficient quota. |
API key | Use a dedicated key for each integrator | Improves fault isolation and audit granularity. |
Image content | Do not include any credentials | Prevents credential disclosure if an image is leaked. |
Kubernetes environment variables | Clear and override | Prevents cluster information disclosure. |