Custom Runtime Image
Custom Runtime Images are available exclusively with the Professional package. Contact us to learn more about upgrading your subscription.
Overview
StackGuardian provides a base variant of the Terraform/OpenTofu runtime image that you can extend with your own tools and dependencies.
Prerequisites:
- Docker 20.10+
- Access to the StackGuardian container registry
Base Image
StackGuardian provides a base runtime image that you can use as your parent image. It includes:
- Pre-cached OpenTofu and Terraform binaries with on-demand version resolution
- OPA, Infracost, and Terragrunt
- Python 3.12 runtime and the StackGuardian workflow application
- A non-root
stackguardianuser (UID 911)
The base image URL is available in your Organization Settings → Runner Groups in the StackGuardian platform. In the examples below, it is referred to as <BASE_IMAGE>.
The base image has a fully functional Alpine package manager (apk) and pip and is the supported starting point for installing additional system or Python dependencies.
Writing your Dockerfile
FROM <BASE_IMAGE>
# Switch to root to install packages
USER root
# Install system packages
RUN apk add --no-cache \
aws-cli \
azure-cli \
jq \
bash
# Install Python packages
RUN pip install --no-cache-dir \
boto3 \
requests
# Switch back to the application user
USER stackguardian
Key rules:
- Switch to
USER rootbefore installing packages. - Switch back to
USER stackguardianwhen done. - Do not override
ENTRYPOINTorCMD-- the application entrypoint is already configured. - Do not modify files under
/usr/local/bin/-- these are the cached IaC tool binaries.
Examples
AWS CLI + 1Password CLI
FROM <BASE_IMAGE>
USER root
RUN apk add --no-cache aws-cli
RUN wget -q -O /tmp/op.zip \
https://cache.agilebits.com/dist/1P/op2/pkg/v2.24.0/op_linux_amd64_v2.24.0.zip && \
unzip /tmp/op.zip -d /usr/local/bin/ && \
rm /tmp/op.zip && \
chmod +x /usr/local/bin/op
USER stackguardian
Custom Python Libraries
FROM <BASE_IMAGE>
USER root
RUN pip install --no-cache-dir \
checkov \
pyyaml
USER stackguardian
Azure CLI with Extensions
FROM <BASE_IMAGE>
USER root
RUN apk add --no-cache \
py3-pip \
gcc \
musl-dev \
python3-dev \
libffi-dev
RUN pip install --no-cache-dir azure-cli
USER stackguardian
Security hardening (Optional)
The base image ships a hardening script at /usr/local/bin/harden.sh. This script strips the image down for production use by:
- Removing unnecessary system accounts
- Removing SUID/SGID binaries and dangerous commands
- Removing admin commands from
/sbinand/usr/sbin(exceptapk) - Disabling interactive login shells
- Locking down file permissions
apk and pip remain available after hardening so that downstream images can still install packages if needed.
To apply hardening after installing your packages:
FROM <BASE_IMAGE>
USER root
RUN apk add --no-cache aws-cli
RUN pip install --no-cache-dir boto3
# Apply security hardening (must be the last RUN step as root)
RUN /usr/local/bin/harden.sh stackguardian
USER stackguardian
Run harden.sh as the last root step in your Dockerfile. Most admin tools and system commands will be removed after hardening. Only apk and pip are preserved for package management.
Build and test
# Build your custom image
docker build -t my-custom-runtime:latest .
# Verify your tools are available
docker run --rm my-custom-runtime:latest aws --version
docker run --rm my-custom-runtime:latest pip list
# Verify the application still starts
docker run --rm my-custom-runtime:latest
Working directory
The application working directory is /opt/stackguardian. Avoid writing to this directory as it contains the application code. Use /tmp or /mnt for temporary files. To find the workflow's workspace and artifacts directory, read the SG_MOUNTED_WORKSPACE_ROOT_DIR and SG_MOUNTED_ARTIFACTS_DIR variables. See Runtime environment variables.
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
apk add fails with permission denied | Not running as root | Add USER root before install commands |
apk add fails with "not found" | Using the hardened image instead of base | Use the base image provided in your Organization Settings |
| Application fails to start | CMD or ENTRYPOINT was overridden | Remove any CMD/ENTRYPOINT from your Dockerfile |
| Binary not found at runtime | Installed to wrong path | Ensure binaries are in /usr/local/bin/ or on $PATH |