Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ __pycache__/
*.key
*.pem
TIKTOKEN_CACHE
PRISMA_CACHE
# Ignore only top-level docs directory, not lib/docs
/docs/

Expand Down
22 changes: 22 additions & 0 deletions lib/api-base/fastApiContainer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,28 @@ export class FastApiContainer extends Construct {
// Continue execution even if cache generation fails
}
}

// When prepareDockerOffline is enabled, pre-generate the Prisma engine binary cache.
// This downloads Prisma engine binaries from binaries.prisma.sh for the target
// container platform and places them in PRISMA_CACHE/ so the Docker build can use
// them without internet access. Same pattern as the tiktoken cache generation above.
if (config.prepareDockerOffline && process.env.NODE_ENV !== 'test') {
const prismaCacheDir = path.join(REST_API_PATH, 'PRISMA_CACHE');
console.log('prepareDockerOffline: Generating Prisma engine binary cache for offline builds...');
try {
const scriptPath = path.join(ROOT_PATH, 'scripts', 'generate-prisma-cache.py');
const platform = config.restApiConfig.buildConfig?.PRISMA_PLATFORM || 'debian-openssl-3.0.x';
child_process.execSync(`python3 ${scriptPath} ${prismaCacheDir} --platform ${platform}`, { stdio: 'inherit' });
} catch (error) {
console.error('prepareDockerOffline: Failed to generate Prisma cache:', error);
throw new Error(
'Failed to generate Prisma engine binary cache for offline builds. ' +
'Ensure internet access is available and prisma-client-py is installed (pip install prisma). ' +
'Set prepareDockerOffline: false to skip this step.',
{ cause: error }
);
}
}
}

const restApiImage = config.restApiConfig.imageConfig || {
Expand Down
37 changes: 23 additions & 14 deletions lib/docs/admin/deploy.md
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,15 @@ baseImage: <adc-registry>/python:3.13-slim
restApiConfig:
buildConfig:
PRISMA_CACHE_DIR: "./PRISMA_CACHE" # Path relative to lib/serve/rest-api/
PRISMA_PLATFORM: "debian-openssl-3.0.x" # Must match container base image OS (default)

# Configure offline build dependencies for MCP Workbench (S6 Overlay and rclone)
mcpWorkbenchBuildConfig:
S6_OVERLAY_NOARCH_SOURCE: "./s6-overlay-noarch.tar.xz" # Path relative to lib/serve/mcp-workbench/
S6_OVERLAY_ARCH_SOURCE: "./s6-overlay-x86_64.tar.xz" # Path relative to lib/serve/mcp-workbench/
RCLONE_SOURCE: "./rclone-linux-amd64.zip" # Path relative to lib/serve/mcp-workbench/
# During synthesis, this will predownload tiktoken and prisma caches for rest-api. The folder will be added into the container, removing the need to download during the container build process
prepareDockerOffline: true
```

You'll also want any model hosting base containers available, e.g. vllm/vllm-openai:latest and ghcr.io/huggingface/text-embeddings-inference:latest
Expand All @@ -446,31 +449,37 @@ For environments without internet access during Docker builds, you can pre-cache

**REST API Prisma cache** (required by prisma-client-py):

The `prisma-client-py` package requires platform-specific binaries and a Node.js environment to function. When Prisma runs for the first time, it downloads these dependencies to `~/.cache/prisma/` and `~/.cache/prisma-python/`. For offline deployments, you need to pre-populate this cache.
The `prisma-client-py` package requires platform-specific engine binaries to function. For offline deployments, you need to pre-download these binaries so the Docker build doesn't need internet access.

Below is an example workflow using an Amazon Linux 2023 instance with Python 3.12:
LISA includes a helper script that downloads the correct engine binaries for the target container platform, regardless of what OS your build machine runs:

```bash
# Ensure Pip is up-to-date
# Ensure pip is up-to-date
pip3 install --upgrade pip

# Install Prisma Python package
# Install Prisma Python package (needed to determine the engine version)
pip3 install prisma

# Trigger Prisma to download all required binaries and create its Node.js environment
# This populates ~/.cache/prisma/ and ~/.cache/prisma-python/
prisma version
# Download Prisma engine binaries for the target container platform
# Defaults to debian-openssl-3.0.x (matches python:3.13-slim)
python3 scripts/generate-prisma-cache.py lib/serve/rest-api/PRISMA_CACHE/
```

The script downloads `query-engine` and `schema-engine` binaries directly from `binaries.prisma.sh` for the target platform. This is preferred over running `prisma version` (which downloads binaries for your *current* host OS) because the build machine often differs from the container OS — e.g. building on Amazon Linux or macOS while the container uses Debian-based `python:3.13-slim`.

To target a different container base image, use the `--platform` flag:

```bash
# For Amazon Linux 2023 / RHEL 9 based containers
python3 scripts/generate-prisma-cache.py lib/serve/rest-api/PRISMA_CACHE/ --platform rhel-openssl-3.0.x

# Copy the complete Prisma cache to your build context
# The wildcard captures both 'prisma' and 'prisma-python' directories
cp -r ~/.cache/prisma* lib/serve/rest-api/PRISMA_CACHE/
# For Alpine based containers
python3 scripts/generate-prisma-cache.py lib/serve/rest-api/PRISMA_CACHE/ --platform linux-musl-openssl-3.0.x
```

**Important Notes:**
You can also set `PRISMA_ENGINES_MIRROR` to use an internal mirror if `binaries.prisma.sh` is not accessible from your network.

* The cache is platform-specific. Generate it on a system matching your Docker base image (e.g., for `public.ecr.aws/docker/library/python:3.13-slim` which is Debian-based, so you may want to use a Debian-based system)
* The `prisma version` command downloads binaries for your current platform
* Both `prisma/` and `prisma-python/` directories are required for offline operation
When using `prepareDockerOffline: true`, the platform can be configured in `config-custom.yaml` via `restApiConfig.buildConfig.PRISMA_PLATFORM` (defaults to `debian-openssl-3.0.x`).

**MCP Workbench dependencies** (S6 Overlay and rclone):

Expand Down
15 changes: 0 additions & 15 deletions lib/rag/ingestion/ingestion-image/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,21 +1,6 @@
ARG BASE_IMAGE=public.ecr.aws/lambda/python:3.13
FROM ${BASE_IMAGE}

# Apply SSH security hardening - disable weak ciphers (3DES-CBC, etc.)
RUN mkdir -p /etc/ssh && \
echo "" >> /etc/ssh/ssh_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/ssh_config && \
echo "Host *" >> /etc/ssh/ssh_config && \
echo " Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/ssh_config && \
echo " MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/ssh_config && \
echo " KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/ssh_config && \
if [ -f /etc/ssh/sshd_config ]; then \
echo "" >> /etc/ssh/sshd_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/sshd_config && \
echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/sshd_config && \
echo "MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/sshd_config && \
echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/sshd_config; \
fi

ARG BUILD_DIR=build

Expand Down
19 changes: 11 additions & 8 deletions lib/schema/configSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,12 @@ export enum ModelType {
* @property {string} pgVectorSecurityGroupId - Security Group ID.
*/
export const SecurityGroupConfigSchema = z.object({
modelSecurityGroupId: z.string().startsWith('sg-'),
restAlbSecurityGroupId: z.string().startsWith('sg-'),
lambdaSecurityGroupId: z.string().startsWith('sg-'),
liteLlmDbSecurityGroupId: z.string().startsWith('sg-'),
openSearchSecurityGroupId: z.string().startsWith('sg-').optional(),
pgVectorSecurityGroupId: z.string().startsWith('sg-').optional(),
modelSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-'),
restAlbSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-'),
lambdaSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-'),
liteLlmDbSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-'),
openSearchSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-').optional(),
pgVectorSecurityGroupId: z.string().regex(/^sg-/, 'Must start with sg-').optional(),
})
.describe('Security Group Overrides used across stacks.');

Expand Down Expand Up @@ -728,7 +728,8 @@ const FastApiContainerConfigSchema = z.object({
sslCertIamArn: z.string().nullish().default(null).describe('ARN of the self-signed cert to be used throughout the system'),
imageConfig: ImageAssetSchema.optional().describe('Override image configuration for ECS FastAPI Containers'),
buildConfig: z.object({
PRISMA_CACHE_DIR: z.string().optional().describe('Override with a path relative to the build directory for a pre-cached prisma directory. Defaults to PRISMA_CACHE.')
PRISMA_CACHE_DIR: z.string().optional().describe('Override with a path relative to the build directory for a pre-cached prisma directory. Defaults to PRISMA_CACHE.'),
PRISMA_PLATFORM: z.string().optional().describe('Prisma engine binary platform target for offline cache generation. Must match the container base image OS. Defaults to debian-openssl-3.0.x (matches python:3.13-slim). Common values: debian-openssl-3.0.x, rhel-openssl-3.0.x, linux-musl-openssl-3.0.x.')
}).default({}),
rdsConfig: RdsInstanceConfig
.default({
Expand Down Expand Up @@ -895,7 +896,7 @@ export const RawConfigObject = z.object({
batchIngestionConfig: ImageAssetSchema.optional().describe('Image override for Batch Ingestion'),
vpcId: z.string().optional().describe('VPC ID for the application. (e.g. vpc-0123456789abcdef)'),
subnets: z.array(z.object({
subnetId: z.string().startsWith('subnet-'),
subnetId: z.string().regex(/^subnet-/, 'Must start with subnet-'),
ipv4CidrBlock: z.string(),
availabilityZone: z.string().describe('Specify the availability zone for the subnet in the format {region}{letter} (e.g., us-east-1a).'),
})).optional().describe('Array of subnet objects for the application. These contain a subnetId(e.g. [subnet-fedcba9876543210] and ipv4CidrBlock'),
Expand Down Expand Up @@ -1025,6 +1026,8 @@ export const RawConfigObject = z.object({
convertInlinePoliciesToManaged: z.boolean().optional().default(false).describe('Convert inline policies to managed policies'),
iamRdsAuth: z.boolean().optional().default(false)
.describe('Enable IAM authentication for RDS. When true (default), IAM authentication is used and the bootstrap password is deleted after setup. When false, password-based authentication is used. WARNING: Switching from true to false after deployment is not supported - the master password is permanently deleted when IAM auth is enabled. This is a one-way migration.'),
prepareDockerOffline: z.boolean().default(false)
.describe('When true, pre-generates all Docker build dependencies (tiktoken cache, Prisma engine binaries) during CDK synth so that subsequent Docker builds can run in an airgapped environment without access to binaries.prisma.sh or other external hosts. Requires Docker and internet access on the synth machine.'),
});

export const RawConfigSchema = RawConfigObject
Expand Down
16 changes: 2 additions & 14 deletions lib/serve/ecs-model/embedding/instructor/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,8 @@ FROM ${BASE_IMAGE}
RUN apt-get update -y && apt-get upgrade -y && rm -rf /var/lib/apt/lists/*

# Apply SSH security hardening - disable weak ciphers (3DES-CBC, etc.)
RUN mkdir -p /etc/ssh && \
echo "" >> /etc/ssh/ssh_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/ssh_config && \
echo "Host *" >> /etc/ssh/ssh_config && \
echo " Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/ssh_config && \
echo " MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/ssh_config && \
echo " KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/ssh_config && \
if [ -f /etc/ssh/sshd_config ]; then \
echo "" >> /etc/ssh/sshd_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/sshd_config && \
echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/sshd_config && \
echo "MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/sshd_config && \
echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/sshd_config; \
fi
COPY ssh-hardening.sh /tmp/ssh-hardening.sh
RUN chmod +x /tmp/ssh-hardening.sh && /tmp/ssh-hardening.sh && rm /tmp/ssh-hardening.sh

#### POINT TO NEW PYPI CONFIG
ARG PYPI_INDEX_URL
Expand Down
16 changes: 2 additions & 14 deletions lib/serve/ecs-model/embedding/tei/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,8 @@ ARG BASE_IMAGE=ghcr.io/huggingface/text-embeddings-inference:latest
FROM ${BASE_IMAGE}

# Apply SSH security hardening - disable weak ciphers (3DES-CBC, etc.)
RUN mkdir -p /etc/ssh && \
echo "" >> /etc/ssh/ssh_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/ssh_config && \
echo "Host *" >> /etc/ssh/ssh_config && \
echo " Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/ssh_config && \
echo " MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/ssh_config && \
echo " KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/ssh_config && \
if [ -f /etc/ssh/sshd_config ]; then \
echo "" >> /etc/ssh/sshd_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/sshd_config && \
echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/sshd_config && \
echo "MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/sshd_config && \
echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/sshd_config; \
fi
COPY ssh-hardening.sh /tmp/ssh-hardening.sh
RUN chmod +x /tmp/ssh-hardening.sh && /tmp/ssh-hardening.sh && rm /tmp/ssh-hardening.sh

##### Download S3 mountpoints and boto3
ARG MOUNTS3_DEB_URL
Expand Down
26 changes: 26 additions & 0 deletions lib/serve/ecs-model/ssh-hardening.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#!/bin/bash
# LISA Security Hardening - Disable weak SSH ciphers (3DES-CBC, etc.)
set -e

mkdir -p /etc/ssh

# Harden SSH client config
cat >> /etc/ssh/ssh_config <<'EOF'

# LISA Security Hardening - Disable weak ciphers
Host *
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
EOF

# Harden SSH server config if present
if [ -f /etc/ssh/sshd_config ]; then
cat >> /etc/ssh/sshd_config <<'EOF'

# LISA Security Hardening - Disable weak ciphers
Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com
MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com
KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512
EOF
fi
16 changes: 2 additions & 14 deletions lib/serve/ecs-model/textgen/tgi/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,8 @@ ARG BASE_IMAGE=ghcr.io/huggingface/text-generation-inference:latest
FROM ${BASE_IMAGE}

# Apply SSH security hardening - disable weak ciphers (3DES-CBC, etc.)
RUN mkdir -p /etc/ssh && \
echo "" >> /etc/ssh/ssh_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/ssh_config && \
echo "Host *" >> /etc/ssh/ssh_config && \
echo " Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/ssh_config && \
echo " MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/ssh_config && \
echo " KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/ssh_config && \
if [ -f /etc/ssh/sshd_config ]; then \
echo "" >> /etc/ssh/sshd_config && \
echo "# LISA Security Hardening - Disable weak ciphers" >> /etc/ssh/sshd_config && \
echo "Ciphers aes128-ctr,aes192-ctr,aes256-ctr,aes128-gcm@openssh.com,aes256-gcm@openssh.com,chacha20-poly1305@openssh.com" >> /etc/ssh/sshd_config && \
echo "MACs hmac-sha2-256,hmac-sha2-512,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com" >> /etc/ssh/sshd_config && \
echo "KexAlgorithms curve25519-sha256,curve25519-sha256@libssh.org,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512" >> /etc/ssh/sshd_config; \
fi
COPY ssh-hardening.sh /tmp/ssh-hardening.sh
RUN chmod +x /tmp/ssh-hardening.sh && /tmp/ssh-hardening.sh && rm /tmp/ssh-hardening.sh

##### Download S3 mountpoints and boto3
ARG MOUNTS3_DEB_URL
Expand Down
Loading
Loading