Skip to content

Container Image Signing

Sign OCI container images using the QCecuring platform.

QCecuring signs the immutable image digest, not the mutable tag.
All private keys remain protected inside QCecuring and are never exposed to the registry.

Signatures are stored as OCI-compatible artifacts alongside the image.


Container Registry → Resolve Digest → QCecuring Signer → Signing Agent → QCecuring Platform → HSM / KMS

Before signing:

  • QCecuring Platform is running
  • Signing Agent is installed and running
  • A signing key exists in QCecuring
  • Docker CLI is installed
  • You have push access to the registry

Step 1 — View the image on Docker Registry

Section titled “Step 1 — View the image on Docker Registry”

View image on Registry


  1. Navigate to Docker Hub → Personal Access Tokens
  2. Create a new token with Read & Write permissions
  3. Copy the generated token

Create Access Token

After generation:

Copy Access Token


Login using your Docker username:

Terminal window
docker login -u <your-username>

Paste the Personal Access Token when prompted.

Docker Login


Ensure the image exists locally:

Terminal window
docker pull shivam111sharma1/testapp:1.0

Pull Image


Run the QCecuring container signer:

Terminal window
java -jar qcecuring-container-signer.jar sign \
--image shivam111sharma1/testapp:1.0 \
--key-id <YourKeyId>

The signer will:

  1. Resolve the image digest
  2. Generate Cosign-compatible payload
  3. Sign via QCecuring Agent
  4. Upload signature artifact to registry

Sign Image

Expected output:

Image signed successfully

Terminal window
java -jar qcecuring-container-signer.jar verify \
--image shivam111sharma1/testapp:1.0

Verify Signature

Expected:

Signature verification PASSED

Step 7 — View the Signature on Docker Registry

Section titled “Step 7 — View the Signature on Docker Registry”

View Signature on Registry


QCecuring signs:

  • The image digest (sha256:…)
  • The OCI manifest
  • Not the mutable tag

This ensures:

  • Integrity across registry replication
  • Protection against tag retargeting
  • Compatibility with OCI registries

The signer automatically reads credentials from:

~/.docker/config.json

Alternatively, you can provide credentials via environment variables:

Terminal window
export DOCKER_USERNAME=myuser
export DOCKER_PASSWORD=mytoken

- name: Sign Container Image
run: |
java -jar qcecuring-container-signer.jar sign \
--image myrepo/app:${{ github.sha }} \
--key-id ${{ secrets.QCECURING_KEY_ID }}

stage('Sign Image') {
steps {
sh '''
java -jar qcecuring-container-signer.jar sign \
--image myrepo/app:${BUILD_NUMBER} \
--key-id ${QCECURING_KEY_ID}
'''
}
}

Run:

Terminal window
docker login

Ensure:

  • Token has Read & Write permissions
  • Repository exists
  • User has push access

  • Confirm registry supports OCI artifacts
  • Verify digest matches
  • Ensure agent is running

  • Check agent logs
  • Verify key is ACTIVE
  • Confirm policy approval (if enabled)