Control egress
Choose how outbound traffic is allowed or denied, configure inspection, and audit policy decisions from the sandbox.
Deny outbound traffic by default
A default deny policy blocks outbound calls unless a rule allows them. Start 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))
Use --rule "<pattern>:<Action>" for simple host rules. 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
Alternatively, 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 the egress proxy evaluates outbound TLS traffic. Choose the lowest inspection level that supports the policy rules you need.
| Mode | Use when |
|---|---|
Full | You need egress enforcement, including default deny, deny rules, path or method matches, rewrites, or header transforms. This mode also blocks non-HTTP TCP and UDP traffic, except Azure DNS. |
Partial | You only need rewrites or transforms for selected HTTPS hosts. Other HTTPS traffic passes through without request inspection. Deny rules are not supported in this mode. |
None | You do not need the egress proxy for this sandbox. Traffic bypasses proxy inspection and egress policy enforcement. |
- 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, Insert, 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: Insert
name: X-Test-Header
value: egress-test
Rules are evaluated in order. The first matching rule wins.
Verify allowed and blocked hosts
Test from inside the sandbox after the policy has propagated. 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 the policy decision for each host.
- 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
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 for scripts. The JSON output separates allowed and denied decisions.