If your team builds images with Podman, runs research workloads as Apptainer or Singularity SIF files, or ships WebAssembly components through an OCI registry, a scanner that only talks to a Docker daemon will miss most of what you run. Each of the three formats needs a different reader: Podman images come out of the Podman REST API, a SIF file is a single signed file with a squashfs root filesystem, and a Wasm artifact has no operating system at all, so the only dependency list is whatever the build embedded. Scan each one by its digest or hash, check its signatures with keys you control, and treat an empty dependency list from a Wasm binary as unknown rather than clean.
This post is for the platform engineer, the research computing administrator and the AppSec lead who owns "everything that is not a normal Docker image." The first two thirds work with any toolchain. Safeguard enters at "How Safeguard does this."
Key takeaways
- Podman has no read-only API role. Anyone who can open the Podman socket controls Podman as the user who owns it, so the safe setup for any scanner is a dedicated rootless user that holds only the images you want scanned.
- A SIF image is one file with signatures inside it. A scanner should record the file's sha256, check every signature with public keys you trust, and read the root filesystem in place without running or mounting the image.
- A Wasm artifact has no OS packages. The dependency list exists only when the build embedded it (today, Rust built with
cargo auditable). For other languages an empty list means unknown, not clean. - Imports in a Wasm component are capabilities, not vulnerabilities. They tell you what the code can ask the host for; the host decides what it grants.
- Safeguard scans all three as GA integrations: the Podman card and
safeguard podman(GA), the Apptainer / Singularity (SIF) card andsafeguard sif(GA), and the WebAssembly (Wasm) card andsafeguard wasm(GA). Each scan produces an SBOM (SBOM generation and analysis, GA) and vulnerability findings (vulnerability management, GA). - The integration cards are switched on per workspace; the CLI commands work in every workspace. Hosted scans never reach private addresses, so for hosts on an internal network you run the Safeguard CLI (GA) on the host, and results stay on that machine.
- Gating on findings happens through Safeguard policies and gates (GA) in the platform, with Block, Warn and Notify actions and approval through exceptions.
safeguard scanitself exits 0 whatever it finds.
The situation
The trigger is usually an inventory question that nobody can answer. A security review, an audit request or a customer questionnaire asks for "an SBOM and a vulnerability report for every container image you run." The Docker images in the registry are covered. Then someone remembers the rest:
- Build hosts and edge boxes running rootless Podman, with images built locally that never touched a registry.
- An HPC cluster where researchers pull SIF files from a library service or keep them on a shared file system, and run them with Apptainer.
- A plugin platform or edge runtime that loads WebAssembly components pulled from GitHub Container Registry, Harbor or zot.
None of these show up in a scanner that only knows docker pull. A bad week: the auditor wants evidence by Friday, the HPC team says SIF files "are just files," the Wasm team says "it is sandboxed," and the Podman hosts sit on an internal network. Each answer is partly true; none produces evidence.
The fix is not one scanner flag. It is three readers, each matched to how the format stores its contents, plus one place to keep the results and enforce policy on them.
The rules and standards behind it
None of these formats has its own regulation. They inherit the same expectations as any other software you ship or run. This section is general background, not legal or audit advice.
NIST SP 800-190, Application Container Security Guide (September 2017). NIST's container guide treats image risks as their own category (section 3.1), separate from registry, orchestrator, container and host risks. Its countermeasure for image vulnerabilities (section 4.1.1) warns that traditional host-centric tools often cannot see inside containers, which leads to "a false sense of safety," and asks for tools that cover the whole image lifecycle from build to registry to runtime, with visibility into every layer. Section 4.1.5 asks organizations to keep a set of trusted images and registries and allow only those to run. The guide was written for OCI-style containers, but the logic carries over to a Podman store and to a SIF file: know what is inside, know its known vulnerabilities, and know it came from a source you trust.
NIST SP 800-218, the Secure Software Development Framework (SSDF) version 1.1 (February 2022). Practice PS.3, "Archive and Protect Each Software Release," asks producers to archive release files with their integrity verification information (task PS.3.1) and to collect, safeguard, maintain and share provenance data for every component of each release (task PS.3.2). Task PW.4.4 asks you to verify that acquired commercial, open source and other third-party components meet your requirements throughout their life cycles. Task RV.1.1 asks you to gather vulnerability information about your software and the third-party components it uses. A SIF file you distribute to a cluster or a Wasm component you publish to customers is a release under that reading, and the hash, signature status and SBOM recorded with each scan are the kind of integrity and provenance data PS.3 describes.
CISA, 2026 Minimum Elements for a Software Bill of Materials (29 July 2026). CISA, NSA, the FBI and international partners published updated minimum elements that replace the 2021 NTIA list. CISA notes that some software types may need elements beyond the baseline. A Wasm component with no embedded dependency data is a good example of where the baseline is hard to meet from the binary alone and has to come from the build.
The OCI distribution and image specifications. Podman images and Wasm artifacts both live in OCI registries or OCI archives. The image specification defines a manifest that points at a config blob and a list of layers by digest; the distribution specification defines how a client lists tags, pulls manifests and fetches blobs. A digest is the only stable name for an artifact. A tag can move.
The CNCF TAG Runtime Wasm OCI artifact layout. The CNCF working group defines a Wasm artifact as a manifest whose config media type is application/vnd.wasm.config.v0+json with a layer of media type application/wasm. That media type is how a scanner tells a Wasm artifact from an ordinary container image in the same registry.
The SIF format and Apptainer signing. The Singularity Image Format packs the root filesystem, the definition file, metadata and signatures into one file. Apptainer signs with PGP keys by default and also supports PEM keys and X.509 certificates. Verification needs only the public key or certificate.
The WebAssembly core binary format and the Component Model binary format. Both define custom sections, which is where the toolchain name (the producers section) and, for Rust built with cargo auditable, the dependency list live.
Step by step, with or without Safeguard
These steps work with whatever scanner and signing tools you already have. They are ordered so that the inventory comes before the scan and the scan comes before the gate.
Step 1: build one inventory across all three formats
Start with a list, not a scan. For each format, record where the artifacts live and who owns them.
| Format | Where it lives | Stable identity | Who usually owns it |
|---|---|---|---|
| Podman image | A Podman store on a host (rootless per user, or rootful) | Image ID and digest | Platform or build team, per host user |
| SIF image | A library service (library://), an OCI registry (oras://) or a shared file system path | The file's sha256 | Research computing or the HPC admin |
| Wasm artifact | An OCI registry, or .wasm files in a build output | The manifest digest, or the file's sha256 | The plugin or edge platform team |
A useful same-day template is a spreadsheet with these columns: format, location, artifact name, tag, digest or sha256, signed (yes, no, unknown), verified with which key, last scanned, owner. Fill in the first five from listings and leave the rest blank. The blanks are your work list.
On a Podman host you can list the store with standard Podman commands as each user that owns images, because rootless stores are per user. For SIF files on a shared file system, find by extension and record sha256sum for each. For Wasm in a registry, list tags and check each manifest's config media type.
Step 2: pin every artifact to a digest before you scan it
Tags move. If you scan app:1.2 at 10:00 and someone pushes a new app:1.2 at 10:05, your report describes an artifact that is no longer there. For every scan, resolve the tag first, record the digest or hash, and scan exactly those bytes.
- Podman: resolve the tag to the image ID on the host, then export that image.
- SIF from a library: compare the downloaded file with the hash the library names. From an OCI registry: compare the layer with the digest in its manifest.
- Wasm: resolve the tag to its manifest digest, then fetch the layer and check it against its digest.
If the bytes do not match the digest, fail the scan and rescan. Do not keep a result you cannot tie to a hash.
Step 3: give the scanner the least access it can work with
Each format has its own trap here.
Podman. The API has no read-only role: whoever can reach the socket can do anything its user can do with Podman. Use a dedicated rootless user, with lingering on so the socket survives logout, whose store holds only the images you want scanned. Reach it over SSH or mutual TLS, never plain TCP.
SIF. Scanning needs pull access only. For a library, create a token for a dedicated user that can read only the collections you want scanned. For an OCI registry holding SIF artifacts, use a robot or service account with pull access to those repositories. Never hand a scanner a signing key: verification uses public keys.
Wasm. Pull access on the repositories that hold Wasm artifacts. Catalog listing is optional and many public registries do not offer it to ordinary users, so be ready to list repositories by name.
Step 4: check signatures with keys you choose
A signature you did not verify is just bytes. For each format, decide which keys you trust and verify against them.
- SIF: Apptainer can sign with PGP or with PEM keys and X.509 certificates. Keep the public keys or certificate roots you trust in one place and verify against them. Treat "signed but not verified" as a finding, not a pass.
- Wasm: cosign-style signatures can sit on the registry in a
sha256-DIGEST.sigtag or be found through the OCI 1.1 referrers API. A keyed signature can be verified with your public key; its payload must name this artifact's manifest digest. Keyless signatures need identity and issuer checks with the signing tool's own verify command. - Podman: image signature policy is enforced by the container runtime's policy configuration at pull time. A scanner reading the local store sees what is there, not whether it was verified when it was pulled, so keep the pull-time policy in place.
Step 5: scan with the right reader for each format
| Question | Podman image | SIF image | Wasm artifact |
|---|---|---|---|
| Is there an OS layer? | Yes | Yes, the squashfs root filesystem | No |
| Where do dependencies come from? | OS package databases and language manifests in the layers | OS package databases and language manifests in the root filesystem | Only what the build embedded (today, Rust with cargo auditable) |
| What does "no findings" mean? | No known vulnerabilities matched the detected packages | Same, for the primary system partition | Nothing matched among embedded dependencies; for other languages, unknown |
| What else should the report show? | The digest, and which running containers use it | sha256 and signature status | Capabilities from imports and exports, toolchain, signature status |
| What should never happen | Write access to the host | Running or mounting the image | Treating an import as a vulnerability |
Step 6: read Wasm capabilities as a permission review
A Wasm component declares what it imports. An import of wasi:sockets or wasi:filesystem says the code can ask the host for network or file access. Whether it gets it depends on the host runtime's configuration. Read capability output the way you would read the permission list of a mobile app: does this plugin need outbound HTTP? Does a pure data transform need file system access? Language standard libraries often import file system and environment interfaces even when the program never calls them, so a capability on its own is a question for the owner, not a finding to file.
Step 7: decide what blocks and what warns
Write down the rule before the first scan, not after. A workable starting policy for these three formats:
| Condition | Action |
|---|---|
| Critical or high vulnerability with a fixed version available, in a Podman or SIF image headed for production | Block |
| SIF image unsigned, or signed but not verified with a trusted key | Warn, then Block after a set date |
| Wasm artifact with no embedded dependency list | Warn and ask the owner to rebuild with dependency embedding where the language supports it |
| Wasm capability that reaches outside the sandbox (network, file system, HTTP) and is not on the plugin's approved list | Notify the plugin owner |
| Anything blocked that the business must ship | An exception with an owner, a reason and an expiry date |
Keep the exception path real. If the only way past a block is to turn the gate off, people will turn the gate off.
Step 8: rescan on a schedule
None of these sources push events in a standard way. The OCI distribution spec has no standard push notification, SIF libraries do not send scan events, and Podman has no webhooks. Vulnerability data changes daily, so an image that was clean last month may not be clean today. Rescan on a schedule and on every new tag.
Why Podman images need their own reader
Podman is daemonless. There is no Docker daemon to ask, and a rootless user's images live in that user's own store. A scanner that expects /var/run/docker.sock sees nothing.
Podman does expose a REST API through podman system service, usually activated by the podman.socket systemd unit. That API can list images and containers and export an image as an archive. The podman save manual documents the oci-archive and docker-archive formats, which any OCI-aware scanner can read without a daemon.
For what changes when you move to rootless containers in general, see what breaks when you run containers rootless with Podman. Three practical points follow:
- Rootless means per user. Each user who builds or runs images has a separate store and a separate socket at
/run/user/UID/podman/podman.sock. The rootful store is at/run/podman/podman.sock. An inventory has to visit each. - Remote access has two safe options. SSH stream forwarding to the socket, which
podman --remotealready uses, or mutual TLS on the service. Podman 5.7 added TLS and mutual TLS options topodman system service.
Images Podman pulled from a public or private registry are also in that registry. Scan them there, where the registry is the source of truth, and use the host reader for what exists only on the host: images built locally, and the mapping from running containers to image digests.
Why SIF images need their own reader
SIF exists because shared HPC systems cannot give every user a container daemon with root privileges. A SIF file is one immutable file. Apptainer and SingularityCE run it directly, and research teams copy it around like any other file.
Our earlier post on Apptainer vs Docker on shared clusters covers why. That design has three consequences for scanning:
- The root filesystem is squashfs inside the file. A scanner should read it in place. There is no reason to run, mount or unpack the image to inventory it, and on a shared cluster there are good reasons not to.
- Signatures live inside the file. Apptainer can add PGP signatures, or PEM and X.509 signatures in DSSE envelopes, to the SIF itself. A scan that ignores them throws away the provenance the format was designed to carry.
- Sources vary. SIF files come from a Library API service (
library://), from an OCI registry that stores them as artifacts (oras://, pushed withapptainer push image.sif oras://REGISTRY/REPOSITORY:TAG), or from a path on a shared file system. Images that Apptainer runs fromdocker://are ordinary OCI images and belong to the registry they came from.
A timing note for anyone still using the Sylabs Cloud Library: Safeguard's Apptainer page records that cloud.sylabs.io closes on 22 October 2026. Apptainer itself has no default library, so check your remote endpoint configuration and move collections to a library service or an OCI registry you control.
Why Wasm artifacts need their own reader
A WebAssembly module or component is a binary for a virtual instruction set. There is no operating system inside it and no package database to read. That is why a container scanner pointed at a Wasm artifact returns either an error or an empty report, and why the empty report is misleading.
What the binary does carry:
- Kind, size and hash. Whether it is a core module or a component.
- The producers custom section. The WebAssembly tool conventions define a section that records the language and toolchain versions that produced the binary. It is metadata about the build, not a dependency list.
- Imports and exports. For a component, these are WIT interfaces with versions, such as
wasi:http/outgoing-handler. For a core module built for WASI preview 1, they are function names such aspath_open. - Embedded dependency data, sometimes.
cargo auditableembeds the Rust dependency tree in a custom section of the binary it builds. When it is there, the crates can be matched against advisories. When it is not, there is no reliable way to recover the dependency list from the binary. - Other custom sections. Names, source map URLs, build IDs and DWARF debug sections, which matter if you care about what you are shipping alongside the code.
The honest reading: for Rust components built with cargo auditable build --target wasm32-wasip2, you get a real dependency scan. For Go, TinyGo, C and C++, AssemblyScript and JavaScript components, you usually get only the toolchain name. The SBOM for those has to come from the build system, not from the binary.
How do you prove a SIF image was not altered?
Record the sha256 of the file at scan time, verify every signature against public keys you trust, and keep both with the scan result. If the image came from a library, check the downloaded file against the hash the library names; from an OCI registry, check the layer against its manifest digest. A mismatch fails the scan. If you rely on legacy signatures from Singularity before 3.6, treat them as weaker and plan to re-sign. The full verification walkthrough is in how do I verify an Apptainer container signature.
Is a Wasm component with no findings safe to run?
No. "No findings" means no embedded dependency matched a known advisory, and only if the build embedded one. It says nothing about the source code, and it says nothing about what the host grants. A Wasm sandbox limits what the code can reach to what the host provides; it does not fix a memory bug in a C library compiled into the component. Review capabilities, confirm the build embedded its dependencies, and check the signature. Two related reads: is WebAssembly safe if the C library inside has a bug and how to vet a WebAssembly module before you run it.
How Safeguard does this
Safeguard handles all three formats through the Integrations page and through the Safeguard CLI. The steps below follow docs.safeguard.sh as of 25 October 2026. Commands are copied from the docs; we did not run them for this post.
Before you start: each of the three integration cards (Podman, Apptainer / Singularity (SIF), and WebAssembly (Wasm)) is switched on per workspace. If you do not see a card under Integrations, ask your Safeguard contact. The safeguard podman, safeguard sif and safeguard wasm CLI commands work in every workspace.
Podman (GA)
The Podman card connects Safeguard to the images in a Podman store through the Podman REST API. Safeguard lists every image repository and tag on the host and how many running containers use each one. Each image you select becomes a project that Safeguard scans for an SBOM and vulnerability findings. Every scan resolves the tag to its image ID on the host, streams exactly that image to the scanner and records its digest.
Safeguard only reads from Podman: it lists images and containers and exports images. It never creates, starts, stops or deletes anything. The docs say plainly that Podman has no read-only API role and recommend a dedicated rootless user that holds only the images you want scanned.
Hosted, with the Podman card:
- As the user that owns the images, start the API socket:
systemctl --user enable --now podman.socket. Keep it running after logout withsudo loginctl enable-linger USER. For rootful Podman usesudo systemctl enable --now podman.socket. - For SSH, create a key pair for Safeguard and add the public key to that user's
~/.ssh/authorized_keys. The docs showssh-keygen -t ed25519 -f safeguard-podman -C safeguard. Print the host key withssh-keyscan -t ed25519 HOSTand check its fingerprint with the host's owner. - For mutual TLS (Podman 5.7 or later), issue a server certificate and a client certificate from your CA and start the service with TLS, as the docs show:
podman system service --time 0 --tls-cert server.pem --tls-key server-key.pem --tls-client-ca ca.pem tcp://0.0.0.0:8888
- In Safeguard, open Integrations and choose the Project/Product tab. Click Connect on the Podman card.
- Enter a Name, then choose SSH or Mutual TLS under Connection.
- Enter the Podman service URL. For rootless:
ssh://USER@HOST/run/user/UID/podman/podman.sock. For rootful:ssh://root@HOST/run/podman/podman.sock. For TLS:tcp://HOST:PORTorhttps://HOSTbehind a proxy that requires a client certificate. - For SSH, paste the private key, its passphrase if it has one, and the host public key. For mutual TLS, paste the client certificate, the client private key and, for a private CA, the CA certificate.
- Click Verify connection. Success shows how many images are on the host.
- Click Next, pick the image repositories and tags to scan, and finish.
The hosted scanner only reaches public addresses. If the host resolves to a private, loopback or link-local address, the docs say to run safeguard podman scan on the host instead.
On the host, with the Safeguard CLI:
The docs recommend this route for hosts the internet cannot reach. No Docker and no inbound connection are needed. If you are new to the CLI, start with scan container images from the terminal.
safeguard podman ping # finds the socket and shows the Podman version
safeguard podman images # every image with its ID and digest
safeguard podman containers --all # containers with the digest of the image they run
safeguard podman inventory --json # running containers grouped by image digest
safeguard podman scan --running # scan the images of running containers
safeguard podman scan --all --json # scan every image in the store
safeguard scan --image podman:docker.io/library/alpine:3.20
safeguard scan --image oci-archive:./alpine.tar # from podman image save --format oci-archive
The CLI finds the socket the way podman --remote does: the --url flag, then CONTAINER_HOST, then the user's runtime directory, then the rootless and rootful default paths. It can also reach another host over SSH with --identity and host key checks against ~/.ssh/known_hosts, or over mutual TLS with --tls-ca, --tls-cert and --tls-key. The CLI usage page adds that safeguard podman scan reads each image one of three ways (--via api, the default, exports it over the API as an OCI archive; --via save runs podman image save), and that safeguard scan --image also reads docker-archive:, oci-archive: and oci-dir: sources.
What Safeguard reads and keeps: the Podman version, the image list, the container list and, for each scan, the selected image exported as an OCI archive. Nothing is written to the host. Safeguard stores the SBOM, the findings, and the image ID and digest of each scan. The service URL and credential are encrypted at rest and never shown again. The image archive is deleted with the scan's working folder when the scan ends. The docs state that no customer data from this integration is sent to third-party LLMs.
Rotation: create the new key or certificate, open the connection's edit dialog, paste it, click Verify connection and save. Then remove the old public key or revoke the old certificate.
Apptainer / Singularity (SIF) (GA)
The Apptainer / Singularity (SIF) card scans images in the Singularity Image Format. Each image you select becomes a project. Every scan downloads the SIF, records its sha256, checks every signature in it (PGP, and X.509 or PEM keys in DSSE envelopes), and builds the SBOM and vulnerability findings of its root filesystem. Nothing in the image is run, mounted or unpacked: the scanner reads the squashfs root filesystem in place.
It reads from a Library API service (library://) or from an OCI registry holding SIF artifacts (oras://). Safeguard only reads; it never pushes, deletes, signs or changes an image, tag or collection, and it never needs a signing key.
Hosted, with the SIF card:
- Create the credential. For a library, sign in to its web interface, open Access Tokens, and create a token for a user that can read the collections to scan. For an ORAS registry, create a robot or service account with pull access to the SIF repositories.
- Optional check before connecting:
apptainer remote login(library) orapptainer registry login oras://REGISTRY(registry), thenapptainer pullone image. - In Safeguard, open Integrations, choose the Project/Product tab and click Connect on the Apptainer / Singularity (SIF) card.
- Enter a Name, then choose the Source (Library or OCI registry) and the Access (Public or Private).
- Enter the Library URL or the Registry host.
- Under Images, add one image per line:
entity/collection/container:tagfor a library,repository/name:tagfor a registry. For a library you can also add entities or collections to list. - For Private, enter the library access token, or the registry username and token or password.
- Click Verify access, then Next, pick the images and tags to scan, and finish.
On an HPC host, with the Safeguard CLI:
safeguard sif inspect image.sif # header, objects, architecture, definition file, labels
safeguard sif verify image.sif --key signer.asc # PGP public key or PEM public key
safeguard sif verify image.sif --certificate leaf.pem --certificate-roots ca.pem
safeguard sif scan image.sif # SBOM, vulnerabilities, sha256 and signature status
safeguard scan image.sif # the same scan, from the scan command
For remote sources the docs show the token passed through an environment variable, never a flag: SG_LIBRARY_TOKEN for library:// references and SG_REGISTRY_PASSWORD with --registry-username for oras:// references. safeguard sif also answers to safeguard apptainer and safeguard singularity.
safeguard sif verify has exit codes you can script against: 0 when every object is verified, 2 when a signature or signed object is invalid, and 3 when the image is unsigned or not fully verified. That makes it a usable pre-run check on a cluster: a job wrapper can refuse to start an image that does not return 0. The scan also writes sif-provenance.json with the file's sha256, where it came from, and the signature report. Results stay on the machine.
What Safeguard checks and keeps: the downloaded file against the hash the library names, or the layer against the digest in its manifest. A mismatch fails the scan. Safeguard stores the SBOM, the findings, the SIF's sha256 and the signature status of each scan. The token is encrypted at rest. The SIF file is deleted with the scan's working folder when the scan ends. No customer data from this integration is sent to third-party LLMs.
WebAssembly (Wasm) (GA)
The WebAssembly (Wasm) card connects Safeguard to Wasm components and modules stored as OCI artifacts in any registry that implements the OCI distribution spec. Safeguard lists every repository and tag and says for each tag whether it is a Wasm artifact. Each tag you select becomes a project.
A Wasm scan reads the binary itself: whether it is a core module or a component, its size and sha256; the toolchain from the producers section, recorded as metadata; the WIT interfaces a component imports and exports, with versions, or the imports and exports of a core module; Rust crates embedded by cargo auditable, which are matched against vulnerability advisories; other custom sections such as name, source map URL, build ID and DWARF; and signatures on the OCI artifact. The result is a CycloneDX 1.6 SBOM with the artifact as the main component, plus capability findings.
Capability findings. Safeguard rates imports that reach outside the sandbox (network sockets, DNS lookup, outgoing HTTP, file system, environment variables, and key-value, config, blob or messaging stores) as Low, and ordinary plumbing (standard input and output, clocks and randomness, process exit, command-line arguments, ML inference, serving HTTP, running as a command, and host-defined imports) as Info. Nothing is rated higher, because the docs say an import alone never proves misuse. That matches Step 6 above: capability output is a permission review, not a vulnerability list.
Hosted, with the Wasm card:
- If you have not published a Wasm artifact yet, the docs point to the CNCF TAG Runtime layout and show an
oras pushexample:
oras push registry.example.com/team/app:1.0.0 \
--config config.json:application/vnd.wasm.config.v0+json \
app.wasm:application/wasm
- Build Rust components with
cargo auditable build --target wasm32-wasip2so the dependency list is embedded. - In your registry, create a read-only token or robot account with pull access to the Wasm repositories. For GitHub Container Registry, the docs specify a classic personal access token with
read:packages; fine-grained tokens do not work with GitHub Packages. - In Safeguard, open Integrations, choose the Project/Product tab and click Connect on the WebAssembly (Wasm) card.
- Choose Public or Private. For Public, enter a Name and the repositories, one per line, and click Check repositories. For Private, enter a Name, the Registry host, the Username and the Password or token, optionally list repositories, and click Verify credentials.
- Click Next. Open a repository's tags: each tag shows its digest and whether it is a Wasm artifact.
- Select the repositories and tags and click Connect.
Only https registries are connected; plain http registries are refused. A tag that holds an ordinary container image rather than a Wasm artifact is scanned as a container image.
With the Safeguard CLI:
safeguard wasm inspect ./app.wasm
safeguard wasm scan ./app.wasm -o app.cdx.json
safeguard wasm scan oci://registry.example.com/team/app:1.0.0 --key cosign.pub
echo "$TOKEN" | safeguard wasm scan registry.example.com/team/app:1.0.0 --username ci --password-stdin
The CLI parses Wasm itself; no Wasm runtime and no Docker are needed. It pins the manifest to its digest and checks each Wasm layer against its digest. --no-vulns skips advisory matching, --max-bytes caps the file or layer size and --timeout caps registry access. Every report ends with its limits.
Signatures. Safeguard looks for cosign signatures in the sha256-DIGEST.sig tag and through the OCI 1.1 referrers API. A keyed signature is verified with the public key you give, and its payload must name this artifact's manifest digest; the result is "signed and verified" or "signature present but did not verify." Keyless signatures are reported as "signature present, not verified," and the docs point you to cosign verify with certificate identity and issuer flags for that check. Hosted scans have no public key, so they report presence only.
Bring the results together
Every connected image or tag becomes a project in Safeguard, so Podman images, SIF files and Wasm artifacts sit alongside the rest of your projects with an SBOM (SBOM generation and analysis, GA) and vulnerability findings (vulnerability management with EPSS and KEV enrichment, GA).
- Schedule rescans. None of these sources send webhooks. Images are scanned when you connect them, on the schedule you set under Integrations › Scheduled, or when you rescan by hand.
- Gate on findings in the platform. The CLI usage page is explicit that
safeguard scandoes not fail on findings: it exits 0 when the scan ran, 1 when the command failed, and 2 when results were written but the vulnerability scan did not actually run. There is no severity threshold flag. Gating is done by policies and gates (GA) in the platform. The policies and gates page defines three actions: Block fails the gate, Warn passes it with a warning naming the policy, and Notify passes it and sends a notification. When a release must ship past a failing policy, someone requests an exception and an approver grants or denies it. - Fix what has a fix. For Podman and SIF images, the findings point at OS packages and language dependencies inside the image, and the fix usually lands in the definition file or Containerfile and the repository that builds it. Connect that repository to Safeguard as well, so its dependencies are covered by autonomous remediation (GA), which ships switched off with every category set to Manual.
What Safeguard does not do
- It does not scan private-network hosts from the cloud. The hosted Podman scanner only connects to public addresses. For internal hosts, you run the CLI on the host, and
safeguard podman scanresults stay on that machine; they are not uploaded to the platform. Moving them into the platform is a step you take deliberately. - It does not give Podman a read-only role. Podman has none. Safeguard only reads, but the credential you give it can do anything that socket's user can do. Limiting that is your job, with a dedicated rootless user.
- It does not run container code analysis on Podman host images. The docs list this as a limit for images scanned from a Podman host. The running-container inventory is CLI output only.
- It does not scan every partition of a SIF file, or encrypted SIFs. Only the primary system partition is scanned. Overlay and data partitions are listed by
safeguard sif inspectbut not scanned. Encrypted SIFs cannot be scanned without their key. Scans pull amd64 by default. - It does not decide which signing keys you trust. Hosted SIF scans check signatures against the public keys your workspace trusts; without them a signed image shows as signed but not verified. When a DSSE signature fails with the keys you gave, Safeguard reports it as not verifiable rather than invalid, because it cannot tell a different key from an altered signature. Legacy signatures from Singularity before 3.6 are checked only by the CLI with
--legacy-insecure. - It does not invent a Wasm dependency list. Dependencies are listed only when the build embedded them. Today that is Rust built with
cargo auditable. For Go, TinyGo, C and C++, AssemblyScript and JavaScript components the list is usually empty, and empty means unknown. Build-only crates are listed but not matched. - It does not verify keyless Wasm signatures. They are reported as present, not verified, and the certificate identity is not shown. Use the signing tool's verify command with identity and issuer checks for that.
- It does not decide what a Wasm host grants. Capability findings describe what the code can ask for. Your runtime configuration decides what it gets.
- It does not fail your pipeline from the scan command.
safeguard scanhas no severity threshold flag. If you want a build to stop, set a policy gate in the platform. - It does not replace your registry integrations. Images Podman pulled from a registry, and images Apptainer runs from
docker://, are covered by that registry's integration. Connect the registry for those.
Common mistakes
- Scanning the tag instead of the digest. The report then describes whatever the tag pointed at when someone last looked. Pin first, scan second.
- Running the Podman scanner as root on a rootless host. Root sees the rootful store, not each user's store. Run as the user who owns the images, or visit each.
- Exposing the Podman API on plain TCP "just for the scanner." That is unauthenticated control of Podman. Use SSH or mutual TLS.
- Treating "signed" as "verified." A SIF or Wasm signature means nothing until it checks out against a key you chose.
- Mounting a SIF to inspect it. On a shared cluster that is unnecessary and adds risk. Read the squashfs in place.
- Reading an empty Wasm dependency list as clean. For anything but Rust built with
cargo auditable, it usually means the build did not embed one. - Filing Wasm imports as vulnerabilities.
wasi:filesystemin a standard library build is normal. Ask the owner whether the host should grant it. - Expecting the scan command to fail the build. It exits 0 on findings by design. Put the rule in a gate.
FAQ
Can Safeguard scan Podman images without Docker installed?
Yes. The Safeguard CLI reads the Podman REST API through the local socket, and the docs state that no Docker and no inbound connection are needed. The hosted Podman card connects over SSH or mutual TLS instead.
Does Safeguard need root on the Podman host?
No. Run the CLI, or connect the card, as the rootless user that owns the images. Root, or the rootful socket, is optional and only needed for images stored by rootful Podman.
Can Safeguard scan SIF files on a shared file system?
Yes, with safeguard sif scan /path/image.sif on the host. Nothing is uploaded, and the image is not run or mounted.
Does Safeguard verify Apptainer signatures?
Yes. It checks PGP signatures, and X.509 or PEM keys in DSSE envelopes, against public keys you trust. safeguard sif verify returns 0 when every object is verified, 2 when a signature or signed object is invalid, and 3 when the image is unsigned or not fully verified.
Why does a Wasm scan show no dependencies?
Because the build did not embed them. Today only Rust components built with cargo auditable carry a dependency list Safeguard can match. For other languages, the list is unknown, not empty.
Are Wasm capability findings vulnerabilities?
No. They are rated Low when the capability reaches outside the sandbox and Info for ordinary plumbing. An import says what the code can ask for; the host decides what it grants.
Can I fail a CI job on Wasm or SIF findings?
Not from the scan command itself, which exits 0 when the scan ran. Set a policy gate in Safeguard with Block, Warn or Notify, and handle approvals through exceptions. For SIF signatures specifically, the exit codes of safeguard sif verify can stop a job wrapper.
Is my image or binary kept after the scan?
No. The Podman archive, the SIF file and the Wasm binary are deleted when the scan ends. Safeguard keeps the SBOM, the findings, and the digest or hash and signature status of each scan.
Each of these readers tells you what is inside an artifact and whether a known fix exists. When the fix sits in an upstream package that has not shipped it yet, the next step is the same one that applies to any image or dependency.
Fix it without waiting for upstream
Whatever the vulnerability, most of the risk sits in two gaps. The first is the time between a fix being published and that fix actually running in your production builds. The second, and worse, is the time before any fix exists at all, while a maintainer works out a patch and a release schedule. Waiting through both gaps is a habit, not a requirement. Safeguard gives teams three ways to close them.
1. Autonomous remediation: pull requests, not tickets
When a fixed version exists, Safeguard's Griffin models open a tested, policy gated pull request that moves the affected dependency to the safe version. You can run it on one repository or in bulk across every project that carries the vulnerable version. Remediation categories include dependencies, licenses, security posture and findings, and each one is set separately. Reachability analysis ranks the vulnerable code paths your application actually calls first, so the first pull requests you merge are the ones that matter most. Autonomous remediation ships switched off, with every category set to Manual, so your team decides how much runs on its own and what still needs a human approval.
2. Gold Open Source: the safe version in seconds, free
gold.safeguard.sh is free and needs no login. Search any CVE or package to see affected and fixed versions, CVSS, EPSS, CISA KEV status and a recommended safe version, or use the "Am I affected?" checker. The same data is available through a free read API, README status badges and RSS threat feeds.
3. Gold Registry: start from components that are already fixed
Gold Registry provides hardened, drop in replacements for upstream packages and container images. Every Gold artifact is held continuously to zero exploitable critical or high CVEs and a completed license check, with signed build provenance (signed with Safeguard's key and verifiable with cosign, SLSA Build Level 3 as the design target) and a public evidence page you can hand to an auditor. An artifact loses its Gold badge if it regresses. Teams can point their own package directory at the registry so hardened equivalents resolve without changing how developers install anything.
When upstream has no fix yet, or will not ship one, Safeguard first works to get the fix accepted upstream. If the issue is severe or upstream will not move, Safeguard builds a fork, fixes the vulnerability there and publishes a hardened Gold build, so you are not stuck on a maintainer's release schedule. You can also request a hardened, compatibility tested build of a specific package. Ask which packages it covers before you plan around it.
| Your situation | What to use |
|---|---|
| A fixed version exists | Autonomous remediation opens the upgrade pull request; Gold Open Source confirms the safe version |
| You need to know today whether you are affected | Gold Open Source lookup and "Am I affected?" checker, free and without login |
| You want vulnerable versions to stop shipping | Safeguard policies and gates in CI |
| Upstream has no fix yet, or will not ship one | A custom Gold request; fork and patch |
| You want to start clean on new projects | Pull hardened components and images from Gold Registry |
One honest limit: when the vulnerable code lives in a vendor appliance, a hosted service or an operating system runtime you do not build yourself, the fix still has to come from that vendor or distribution. The steps above apply to the open source dependencies and container images you build and ship, which is where most teams carry the largest and least tracked share of their exposure.
See how Safeguard would help
The first demo is a real Safeguard CLI session: install, safeguard opens the interactive terminal, and a request to fix a lodash CVE in a repository. The CLI reads the finding and the advisory, asks before any command that changes something, edits package.json, runs npm install and npm test with approval, prints a summary and pushes nothing, then shows /permissions, /model and /scan . The same CLI is what runs safeguard podman, safeguard sif and safeguard wasm on a host the hosted scanner cannot reach.
Click through it at your own pace, or open it full screen.
The second demo sets up the local runner on your own machine, approves it with its device code, and then scans from the terminal. That is the route for a build host or an HPC login node: the runner sits where the images are, and nothing needs an inbound connection.
Click through it at your own pace, or open it full screen.
Quick check
A Wasm component written in Go scans with no dependencies and no vulnerabilities. Is it clean?
No. Only builds that embed their dependency list (today, Rust with cargo auditable) give a dependency scan. For Go and most other languages, an empty list means unknown. Get the SBOM from the build system.
Your Podman build host sits on an internal network. How do you scan it with Safeguard?
Run the Safeguard CLI on the host as the user that owns the images, for example safeguard podman scan --all --json. The hosted scanner never connects to private addresses, and CLI results stay on the machine.
Sources
- Safeguard Docs: Podman integration
- Safeguard Docs: Apptainer / Singularity (SIF) integration
- Safeguard Docs: WebAssembly (Wasm) integration
- Safeguard Docs: CLI usage
- Safeguard Docs: Policies and gates
- NIST SP 800-190, Application Container Security Guide
- NIST SP 800-190 full text (PDF)
- NIST SP 800-218, Secure Software Development Framework 1.1
- NIST SP 800-218 full text (PDF)
- CISA: 2026 Minimum Elements for a Software Bill of Materials
- OCI Distribution Specification
- OCI Image Specification: image manifest
- CNCF TAG Runtime: Wasm OCI artifact layout
- Apptainer: Signing and verifying containers
- Apptainer: apptainer push
- sylabs/sif: the SIF format and integrity package
- Podman: podman-system-service(1)
- Podman: podman-save(1)
- WebAssembly core specification: binary format
- WebAssembly Component Model: binary format
- WebAssembly tool conventions: producers section
- cargo-auditable
- CycloneDX 1.6 JSON reference
Try it yourself: download Safeguard or read the docs.
Last reviewed: 25 October 2026. Product capabilities change; check docs.safeguard.sh for the current state.