Add your description here
Project description
🌐 Confidential Router (on Azure Confidential Container)
Permissionless, TEE-based routing for forwarding API calls to providers—running inside an Azure Confidential Container.
Prereqs
-
Azure CLI ≥ 2.44.1 and confcom extension (for CCE policy):
az --version az extension add -n confcom
([Microsoft Learn][1])
-
Docker (to build/push your image).
-
jq + sha256sum (Linux/macOS tools for templating & hashing).
Quick Start (step-by-step)
1) Build & push your image to GHCR
# build
docker build -t ghcr.io/<gh-user>/confidential-router:latest .
# (optional) login if your GHCR is private
# echo $GITHUB_TOKEN | docker login ghcr.io -u <gh-user> --password-stdin
# push
docker push ghcr.io/<gh-user>/confidential-router:latest
# pin by digest (recommended for CCE stability)
IMAGE_DIGEST=$(docker inspect --format='{{index .RepoDigests 0}}' ghcr.io/<gh-user>/confidential-router:latest)
echo "$IMAGE_DIGEST"
2) Login & set variables
# login (interactive) and set subscription if needed
az login
# az account set -s "<SUBSCRIPTION_ID_OR_NAME>"
# choose your names/region
GROUP=confidential-router
LOC=eastus
KV_NAME=confidential-router
MAA_NAME=crmaa
UAMI_NAME=cr-uami
CG_NAME=confrouter # container group name
IMAGE="$IMAGE_DIGEST" # from step 1 (digest form recommended)
# create resource group
az group create -n $GROUP -l $LOC
3) Create MAA (Microsoft Azure Attestation) provider
az attestation create -n $MAA_NAME -g $GROUP -l $LOC
MAA_ENDPOINT=$(az attestation show -n $MAA_NAME -g $GROUP --query 'attestUri' -o tsv)
echo "$MAA_ENDPOINT"
4) Create Key Vault (Premium + RBAC + purge protection)
az keyvault create \
-n $KV_NAME -g $GROUP -l $LOC \
--sku premium \
--enable-rbac-authorization true \
--enable-purge-protection true --retention-days 90
KV_ID=$(az keyvault show -n $KV_NAME -g $GROUP --query id -o tsv)
AKV_ENDPOINT="https://${KV_NAME}.vault.azure.net"
echo "$AKV_ENDPOINT"
5) Create a User-Assigned Managed Identity and assign SKR role
# UAMI
az identity create -g $GROUP -n $UAMI_NAME -l $LOC
UAMI_ID=$(az identity show -g $GROUP -n $UAMI_NAME --query id -o tsv)
UAMI_PRINCIPAL_ID=$(az identity show -g $GROUP -n $UAMI_NAME --query principalId -o tsv)
# Your own admin access (optional but handy)
ME=$(az ad signed-in-user show --query id -o tsv)
az role assignment create --role "Key Vault Administrator" --assignee-object-id $ME --assignee-principal-type User --scope $KV_ID
# **Grant the identity SKR permission** (release action)
az role assignment create \
--assignee-object-id $UAMI_PRINCIPAL_ID \
--assignee-principal-type ServicePrincipal \
--role "Key Vault Crypto Service Release User" \
--scope $KV_ID
6) Prepare the ARM template
Copy your base template and set image + identity + env vars + sidecar:
cp templates/template.base.json templates/template.private.json
Minimal deltas you need inside templates/template.private.json:
{
"type": "Microsoft.ContainerInstance/containerGroups",
"apiVersion": "2023-05-01",
"name": "<CG_NAME>",
"location": "<REGION>",
"identity": {
"type": "UserAssigned",
"userAssignedIdentities": {
"<UAMI_ID>": {}
}
},
"properties": {
"sku": "Confidential",
"confidentialComputeProperties": { "ccePolicy": "" },
"osType": "Linux",
"containers": [
{
"name": "router-container",
"properties": {
"image": "<YOUR_IMAGE_DIGEST>",
"environmentVariables": [
{"name":"AKV_ENDPOINT","value":"https://<kv-name>.vault.azure.net"},
{"name":"MAA_ENDPOINT","value":"https://<maa-name>.<region>.attest.azure.net"},
{"name":"KID","value":"default"},
{"name":"OPENAI_API_KEY","value":"sk-proj-..."},
{"name":"OPENROUTER_API_KEY","value":"sk-or-v1..."},
{"name":"FAL_KEY","value":"4e101177-..."}
],
"ports":[{"port":8080,"protocol":"TCP"}],
"resources":{"requests":{"cpu":2,"memoryInGB":4}}
}
},
{
"name": "skr-sidecar-container",
"properties": {
"image": "mcr.microsoft.com/aci/skr:2.12",
"ports":[{"port":8081,"protocol":"TCP"}],
"resources":{"requests":{"cpu":1,"memoryInGB":1}}
}
}
],
"ipAddress": { "type": "Public", "ports": [ {"port":8080,"protocol":"TCP"} ] },
"restartPolicy": "Always"
}
}
7) Generate the CCE policy (fills template)
az confcom acipolicygen --template-file templates/template.private.json
# This injects a Base64 CCE policy into .resources[0].properties.confidentialComputeProperties.ccePolicy
8) Compute CCE hash and write skr-policy.json
CCE_B64=$(jq -r '.resources[0].properties.confidentialComputeProperties.ccePolicy' templates/template.private.json)
CCE_HASH=$(echo -n "$CCE_B64" | base64 -d | sha256sum | awk '{print $1}')
echo "CCE_HASH = $CCE_HASH"
cat > skr-policy.json <<EOF
{
"version": "1.0.0",
"anyOf": [
{
"authority": "$MAA_ENDPOINT",
"allOf": [
{ "claim": "x-ms-attestation-type", "equals": "sevsnpvm" },
{ "claim": "x-ms-compliance-status", "equals": "azure-compliant-uvm" },
{ "claim": "x-ms-sevsnpvm-hostdata", "equals": "$CCE_HASH" }
]
}
]
}
EOF
9) Create an exportable HSM key with SKR policy
az keyvault key create \
--vault-name $KV_NAME \
--name default \
--kty RSA-HSM --size 2048 \
--exportable true \
--policy @skr-policy.json
10) Deploy the container group & get the IP
az deployment group create \
-g $GROUP \
--template-file templates/template.private.json \
--parameters name=$CG_NAME location=$LOC
IP=$(az container show -g $GROUP -n $CG_NAME --query ipAddress.ip -o tsv)
echo "Public IP: $IP"
11) Smoke test
# (example) if your app serves a health endpoint on 8080
curl -fsS http://$IP:8080/healthz || true
To test SKR from inside your app, call the sidecar at http://localhost:8081/key/release with:
{
"maa_endpoint": "https://<maa-name>.<region>.attest.azure.net",
"akv_endpoint": "https://<kv-name>.vault.azure.net",
"kid": "default"
}
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file confidential_router-0.1.0.tar.gz.
File metadata
- Download URL: confidential_router-0.1.0.tar.gz
- Upload date:
- Size: 17.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5ab7dc9025f979cf32ef815e6e4bef8a11eaac170fe18c9708877abd485f7470
|
|
| MD5 |
1005231c1cabd021b90cc56d8b020234
|
|
| BLAKE2b-256 |
f269ec8223b00355521bdf8a61c3d6ba6f508f2b16d3c9ac469ead457fef20fd
|
File details
Details for the file confidential_router-0.1.0-py3-none-any.whl.
File metadata
- Download URL: confidential_router-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.1 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.8.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ae3afc5efae16e9bf30c8db326af170401e177dec1cf8021914d5a552d8714eb
|
|
| MD5 |
c1a4be03886c05e19411d701cb10b9c7
|
|
| BLAKE2b-256 |
b8c168f4838e3727ed8dad9aeaf04a6fd420f6c37ae47867495035adda6a9f69
|