Air-Gapped Deployments
Run CoreSDK with zero outbound connections — offline policy evaluation, local JWT validation, and manual artifact delivery for air-gapped and disconnected environments.
Air-Gapped Deployments
Phase 3. Air-gapped deployment mode (offline policy bundles, manual JWKS delivery, and disconnected license verification) ships Phase 3.
CoreSDK is designed for zero-trust environments where outbound internet access is restricted or prohibited. Every runtime decision — policy evaluation, JWT validation, license verification — happens locally. No request ever requires an outbound call to a CoreSDK service.
What runs locally
| Operation | How |
|---|---|
| Policy evaluation | Rego engine (regorus) runs in-process; policy bundle loaded from local cache |
| JWT verification | JWK public keys cached locally; signature verified with ring crypto — no JWKS fetch per request |
| License verification | JWS token verified against embedded public key in the binary; no outbound check |
| Config / feature flags | Loaded from local file or HMAC-verified local cache |
| Audit log | Written to local sink (stdout, file, S3-compatible endpoint on your network) |
Sidecar configuration for air-gapped mode
# coresdk-sidecar.yaml
control_plane:
enabled: false # disable all outbound sync
cache:
policy_bundle_path: /etc/coresdk/policy-bundle.tar.gz
config_path: /etc/coresdk/config.yaml
jwks_path: /etc/coresdk/jwks.json
audit:
sink: file
file:
path: /var/log/coresdk/audit.ndjson
rotate_mb: 100
tls:
mode: mtls
ca_cert: /etc/coresdk/ca.crt
server_cert: /etc/coresdk/server.crt
server_key: /etc/coresdk/server.keySet via environment variable:
CORESDK_CONTROL_PLANE_ENABLED=false \
CORESDK_POLICY_BUNDLE_PATH=/etc/coresdk/policy-bundle.tar.gz \
coresdk-sidecar startDelivering policy bundles
In a connected deployment, the sidecar pulls policy bundles from the control plane. In air-gapped mode, you push them manually using the CLI.
Build and sign a bundle
# Compile your Rego policies into a signed bundle
core policy bundle \
--dir ./policies \
--sign-key /etc/coresdk/signing-key.pem \
--output policy-bundle.tar.gz
# Inspect the bundle before deploying
core policy bundle inspect policy-bundle.tar.gz
# → Bundle: policy-bundle.tar.gz
# Policies: 6 (orders, reports, admin, tenant, config, data)
# Signed: yes (ES256)
# Created: 2026-03-19T12:00:00ZDeploy to the sidecar
# Copy the bundle to each host
scp policy-bundle.tar.gz deploy@host1:/etc/coresdk/
scp policy-bundle.tar.gz deploy@host2:/etc/coresdk/
# Reload without restarting
core sidecar reload-policy --bundle /etc/coresdk/policy-bundle.tar.gz
# → Policy bundle loaded and verified. 6 policies active.The sidecar verifies the bundle signature before loading. A tampered or unsigned bundle is rejected.
Automating bundle delivery via CI
#!/usr/bin/env bash
set -euo pipefail
# Build
core policy lint ./policies
core policy test ./policies --fixtures ./tests/policy-fixtures/ --ci
core policy bundle \
--dir ./policies \
--sign-key "$SIGNING_KEY_PEM" \
--output dist/policy-bundle.tar.gz
# Push to your internal artifact registry
aws s3 cp dist/policy-bundle.tar.gz s3://internal-artifacts/coresdk/
# Notify hosts to pull and reload
ansible all -m shell -a \
"aws s3 cp s3://internal-artifacts/coresdk/policy-bundle.tar.gz /etc/coresdk/ && \
core sidecar reload-policy --bundle /etc/coresdk/policy-bundle.tar.gz"Delivering JWKS
If your JWT issuer's JWKS endpoint is not reachable from the sidecar, pre-load the public keys:
# Download JWKS from your IdP (on a machine with internet access)
curl https://your-idp.example.com/.well-known/jwks.json -o jwks.json
# Transfer to air-gapped hosts
scp jwks.json deploy@host1:/etc/coresdk/# coresdk-sidecar.yaml
auth:
jwks_path: /etc/coresdk/jwks.json
jwks_refresh: false # disable automatic refresh attemptsWhen your IdP rotates keys, repeat the manual transfer. Set a reminder to rotate before the old key's exp or at your security team's key rotation schedule.
License tokens
CoreSDK license tokens are pre-signed JWS objects. They are verified against a public key embedded in the sidecar binary — no network call required.
# Deliver your license token (provided by CoreSDK)
cp coresdk-license.jwt /etc/coresdk/license.jwt# coresdk-sidecar.yaml
license:
token_path: /etc/coresdk/license.jwtLicense tokens have a 1-year validity. CoreSDK logs a warning when fewer than 90 days remain. Renew by receiving a new JWS from CoreSDK and repeating the manual delivery.
Binary updates
In air-gapped mode, use the manual update channel:
# Download the new sidecar binary on a machine with internet access
curl -L https://releases.coresdk.io/sidecar/v1.5.0/coresdk-sidecar-linux-amd64 \
-o coresdk-sidecar-v1.5.0
# Verify the signature
core verify binary coresdk-sidecar-v1.5.0 \
--pubkey /etc/coresdk/release-signing-key.pub
# → Signature valid. Binary: coresdk-sidecar v1.5.0 (linux/amd64)
# Transfer and deploy
scp coresdk-sidecar-v1.5.0 deploy@host1:/usr/local/bin/coresdk-sidecar
ssh deploy@host1 "systemctl restart coresdk-sidecar"Disable auto-update to prevent the sidecar from attempting to reach the update endpoint:
# coresdk-sidecar.yaml
auto_update:
enabled: false
channel: manualAudit log export in air-gapped environments
Without cloud sink access, write audit logs to a local file and ship them via your existing log pipeline (Fluentd, Filebeat, etc.):
audit:
sink: file
file:
path: /var/log/coresdk/audit.ndjson
rotate_mb: 100
compress: true # gzip on rotation
keep_rotated: 30 # keep 30 rotated filesFluentd config to forward to an internal SIEM:
<source>
@type tail
path /var/log/coresdk/audit.ndjson
pos_file /var/run/fluentd/coresdk-audit.pos
tag coresdk.audit
<parse>
@type json
</parse>
</source>
<match coresdk.audit>
@type forward
<server>
host siem.internal
port 24224
</server>
</match>Next steps
- Offline Mode — how the sidecar operates during control plane partitions
- Compliance — SOC 2, HIPAA, GDPR alignment
- Configuration Reference — full list of air-gapped config keys
- Self-Hosted — deploying the sidecar in your own infrastructure