Control egress
Choose how outbound traffic is allowed or denied, configure inspection, and audit policy decisions from the sandbox. If no egress policy is specified, the sandbox has unrestricted outbound access. Egress policies are opt-in.
Deny outbound traffic by default
A default deny policy blocks outbound calls unless a rule allows them. Begin with deny, then add the smallest host list your workload needs.
- Open the sandbox from Sandbox groups > your group > Sandboxes.
- From the sandbox details, select Egress policy.
- Set Default action to Deny.
- Set Traffic inspection to Full.
- Add
*.github.comwith action Allow. - Select Save. Wait a few seconds before you test the policy.
- Bash
- PowerShell
- SDK
aca sandbox create --disk ubuntu --label name=demo-egress
aca sandbox egress set -l name=demo-egress --default Deny \
--rule "*.github.com:Allow" \
--traffic-inspection Full
aca sandbox egress show -l name=demo-egress
aca sandbox create --disk ubuntu --label name=demo-egress
aca sandbox egress set -l name=demo-egress --default Deny `
--rule "*.github.com:Allow" `
--traffic-inspection Full
aca sandbox egress show -l name=demo-egress
import os
from azure.identity import DefaultAzureCredential
from azure.containerapps.sandbox import (
EgressHostRule,
EgressPolicy,
SandboxGroupClient,
endpoint_for_region,
)
credential = DefaultAzureCredential()
client = SandboxGroupClient(
endpoint_for_region(os.environ["ACA_SANDBOXGROUP_REGION"]),
credential,
subscription_id=os.environ["AZURE_SUBSCRIPTION_ID"],
resource_group=os.environ["ACA_RESOURCE_GROUP"],
sandbox_group=os.environ["ACA_SANDBOX_GROUP"],
)
sandbox = client.get_sandbox_client(os.environ["SANDBOX_ID"])
sandbox.set_egress_policy(EgressPolicy(
default_action="Deny",
traffic_inspection="Full",
host_rules=[EgressHostRule(pattern="*.github.com", action="Allow")],
))
policy = sandbox.get_egress_policy()
print(policy.default_action, len(policy.host_rules))
For simple host rules, use --rule "<pattern>:<Action>". The action is Allow or Deny.
- Bash
- PowerShell
aca sandbox egress set -l name=demo-egress --default Deny \
--rule "*.github.com:Allow" \
--rule "example.com:Deny" \
--traffic-inspection Full
aca sandbox egress set -l name=demo-egress --default Deny `
--rule "*.github.com:Allow" `
--rule "example.com:Deny" `
--traffic-inspection Full
You can also set the policy when you create a sandbox:
- Bash
- PowerShell
aca sandbox create --disk ubuntu \
--label name=demo-egress \
--egress-default Deny \
--egress-rule "*.github.com:Allow" \
--traffic-inspection Full
aca sandbox create --disk ubuntu `
--label name=demo-egress `
--egress-default Deny `
--egress-rule "*.github.com:Allow" `
--traffic-inspection Full
Allow outbound traffic by default
Use an allow-by-default policy for sandboxes that need normal outbound access, with deny rules for specific destinations.
- Bash
- PowerShell
aca sandbox create --disk ubuntu \
--label name=demo-egress-allow \
--egress-default Allow \
--egress-rule "example.com:Deny" \
--traffic-inspection Full
aca sandbox create --disk ubuntu `
--label name=demo-egress-allow `
--egress-default Allow `
--egress-rule "example.com:Deny" `
--traffic-inspection Full
For an existing sandbox:
- Bash
- PowerShell
aca sandbox egress set -l name=demo-egress --default Allow \
--rule "example.com:Deny" \
--traffic-inspection Full
aca sandbox egress set -l name=demo-egress --default Allow `
--rule "example.com:Deny" `
--traffic-inspection Full
Control traffic inspection
Traffic inspection controls how much request information the egress policy can evaluate. Choose the lowest inspection level that supports your policy rules, and verify exact transport behavior in the current product or CLI help.
| Mode | Use when |
|---|---|
Full | You need the policy to evaluate host rules, path or method matches, rewrites, or header transforms. |
Partial | You need limited inspection for selected policy behaviors. |
None | You do not need egress policy inspection for this sandbox. |
- Bash
- PowerShell
aca sandbox egress set -l name=demo-egress \
--default Deny \
--rule "*.github.com:Allow" \
--traffic-inspection Full
aca sandbox egress set -l name=demo-egress `
--default Deny `
--rule "*.github.com:Allow" `
--traffic-inspection Full
Create-time policy flags support the same inspection setting:
- Bash
- PowerShell
aca sandbox create --disk ubuntu \
--label name=demo-egress \
--egress-default Deny \
--egress-rule "*.github.com:Allow" \
--traffic-inspection Full
aca sandbox create --disk ubuntu `
--label name=demo-egress `
--egress-default Deny `
--egress-rule "*.github.com:Allow" `
--traffic-inspection Full
Use a policy file for advanced rules
Use policy files for path or method matches, rewrites, transforms, and header operations.
Supported rule fields:
| Field | Supported values |
|---|---|
match.host | Required host name or wildcard pattern. |
match.path | Optional path match, such as /headers. |
match.methods | Optional HTTP methods, such as [GET, POST]. |
action.type | Allow, Deny, Rewrite, or Transform. |
action.host | Rewrite target host. Only valid when action.type is Rewrite. |
action.path | Rewrite target path. Only valid when action.type is Rewrite. |
action.scheme | Rewrite target scheme, such as https. Only valid when action.type is Rewrite. |
action.headers | Header mutations. Valid when action.type is Transform or Rewrite. |
headers[].operation | Set, Append, or Remove. Only valid inside action.headers. |
- Bash
- PowerShell
aca sandbox egress init > egress.yaml
aca sandbox egress schema > egress.schema.json
aca sandbox egress apply -l name=demo-egress --file egress.yaml
aca sandbox egress export -l name=demo-egress > current-egress.yaml
aca sandbox egress init > egress.yaml
aca sandbox egress schema > egress.schema.json
aca sandbox egress apply -l name=demo-egress --file egress.yaml
aca sandbox egress export -l name=demo-egress > current-egress.yaml
Example advanced policy:
defaultAction: Deny
trafficInspection: Full
rules:
- name: inject-test-header
match:
host: "httpbin.org"
path: "/headers"
methods: [GET]
action:
type: Transform
headers:
- operation: Append
name: X-Test-Header
value: egress-test
Rules are evaluated in order. The first matching rule wins.
Verify allowed and blocked hosts
After the policy propagates, test from inside the sandbox. An allowed host should return a normal HTTP status. A blocked host should fail or return a non-200 status.
- Open the sandbox, then select Connect > Interactive shell.
- Run
curl https://example.comto test a blocked host. - Run
curl https://api.github.comto test an allowed host. - Select Network audit to review the recorded decisions.
- Bash
- PowerShell
- SDK
aca sandbox exec -l name=demo-egress -c \
"curl -fsS -o /dev/null -w 'HTTP %{http_code}\n' --max-time 8 https://example.com" || echo "blocked"
aca sandbox exec -l name=demo-egress -c \
"curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --max-time 8 https://api.github.com"
aca sandbox exec -l name=demo-egress -c `
"curl -fsS -o /dev/null -w 'HTTP %{http_code}\n' --max-time 8 https://example.com"
if ($LASTEXITCODE -ne 0) { Write-Host "blocked" }
aca sandbox exec -l name=demo-egress -c `
"curl -sS -o /dev/null -w 'HTTP %{http_code}\n' --max-time 8 https://api.github.com"
import time
time.sleep(10)
result = sandbox.exec(
"curl -fsS -o /dev/null -w '%{http_code}' --max-time 8 "
"https://example.com || echo CURL_FAIL"
)
print(result.stdout.strip())
result = sandbox.exec(
"curl -sS -o /dev/null -w '%{http_code}' --max-time 8 "
"https://api.github.com"
)
print(result.stdout.strip())
Audit decisions
The audit view shows outbound connection attempts and each host policy decision.
- Open the sandbox, then select Network audit.
- Use the host filter to find a domain.
- Review the decision, timestamp, and target host for each entry.
- Update Egress policy if the sandbox needs another allowed host.
- Bash
- PowerShell
- SDK
aca sandbox egress decisions -l name=demo-egress
aca sandbox egress decisions -l name=demo-egress -o json
aca sandbox egress decisions -l name=demo-egress
aca sandbox egress decisions -l name=demo-egress -o json
decisions = sandbox.get_egress_decisions()
if decisions.network_egress:
for entry in decisions.network_egress.denied:
print("Denied:", entry.host, entry.method, entry.path)
for entry in decisions.network_egress.allowed:
print("Allowed:", entry.host, entry.method, entry.path)
Use -o json in scripts. The JSON output separates allowed and denied decisions.