Fuzzball Documentation
Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Toggle Dark/Light/Auto mode Back to homepage

SIF Image Decryption

Secrets for decrypting encrypted SIF (Singularity Image Format) images can be specified in a YAML file with the following syntax.

Passphrase-Based Decryption

For SIF images encrypted with a passphrase:

type: sif-decryption-key
secret:
  passphrase: your-encryption-passphrase

PEM Key-Based Decryption

For SIF images encrypted with an RSA public/private key pair:

type: sif-decryption-key
secret:
  pem: |
    -----BEGIN RSA PRIVATE KEY-----
    MIIEpAIBAAKCAQEA2Z3qX5mNr8X...
    [... complete PEM private key content ...]
    -----END RSA PRIVATE KEY-----

Field Descriptions

The sif-decryption-key secret type provides credentials to decrypt encrypted SIF container images at runtime, allowing jobs to use protected container images without exposing the encryption keys in Fuzzfiles.

  • passphrase (optional): The passphrase used to decrypt the SIF image. Use this field for images encrypted with Apptainer’s passphrase-based encryption method.
  • pem (optional): The complete PEM-formatted RSA private key used to decrypt the SIF image that was encrypted with the corresponding RSA public key including the header and footer. Use this field for images encrypted with Apptainer’s PEM key-based encryption method.
passphrase and pem are mutually exclusive.

Usage

Decryption secrets are referenced in a workflow specification using the decryption-secret field of a job’s image configuration:

jobs:
  my-secure-job:
    image:
      uri: oras://registry.example.com/secure/app.sif:latest
      decryption-secret: secret://user/my-decryption-key
    command: [./run-app.sh]

The secret reference follows the standard format: secret://<scope>/<secret-name> where scope is user, account, organization, or cluster.

Creating Encrypted SIF Images

Encrypted SIF images are created using Apptainer. For detailed instructions on creating encrypted containers please refer to the Apptainer Encryption Documentation and see the example below.

Example: Creating and Using an Encrypted Image

1. Create an RSA Key Pair

Generate a 4096-bit RSA key pair:

$ openssl genrsa -traditional -out rsa_private.pem 4096

$ openssl rsa -in rsa_private.pem -RSAPublicKey_out -out rsa_public.pem

Both the private and public keys should be in PKCS#1 format for Apptainer:

  • Use -traditional flag with openssl genrsa to get -----BEGIN RSA PRIVATE KEY----- (PKCS#1 private key format)
  • Use -RSAPublicKey_out flag to get -----BEGIN RSA PUBLIC KEY----- (PKCS#1 public key format)

Without these flags, modern OpenSSL versions default to PKCS#8 format which Apptainer may not accept.

2. Build an Encrypted SIF Image

With a passphrase. The example here is interactive but you can provide the key as an environment variable ($APPTAINER_ENCRYPTION_PASSPHRASE) instead.

$ cat > app.def <<EOF
Bootstrap: docker
From: alpine:latest
EOF

$ apptainer build --passphrase passphrase_app.sif app.def
Enter encryption passphrase:
INFO:    Starting build...
...

With the key created above:

$ apptainer build --pem-path rsa_public.pem key_app.sif app.def

3. Push to a Registry

$ apptainer push key_app.sif oras://registry.example.com/apps/secure-app:v1.0

4. Create Decryption Secret

Create a YAML file (decryption_key_secret.yaml) with your private key:

$ cat > decryption_key_secret.yaml <<EOF
type: sif-decryption-key
secret:
  pem: |
$(sed 's/^/    /' rsa_private.pem)
EOF

Upload the secret:

$ fuzzball secret create secure-app-key \
    --scope user \
    --from-file decryption_key_secret.yaml

5. Use in Workflow

version: v1

jobs:
  run-secure-app:
    image:
      uri: oras://registry.example.com/apps/secure-app:v1.0
      decryption-secret: secret://user/secure-app-key
    script: |
      #!/bin/sh
      echo "Hello from an encrypted container"
    resource:
      cpu:
        cores: 1
      memory:
        size: 1GB

Security Considerations

  1. Protect Private Keys: Never commit PEM private keys to version control or share them insecurely. Use secure secret management practices.
  2. Key Rotation: Regularly rotate encryption keys for enhanced security. This requires re-encrypting images with new keys.
  3. Scope Selection: Choose the narrowest appropriate scope for your decryption secrets:
    • user: for personal development and testing
    • account: for team projects and shared workflows
    • organization: only when images need to be shared across multiple accounts
    • cluster: reserved for system-level images (requires admin privileges)
  4. Separate Concerns: Use different decryption keys for different images or projects to limit the impact if a key is compromised.