Minting and collecting SWID tags

Jan Pazdziora

Sr. Principal Software Engineer
Security Engineering Special Projects, Red Hat
26th January 2019

CC BY-SA License

This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.

This text is also available as slides in PDF format.

Problem space

  • What software is installed on machine X, VM Y, or in container Z?
    • rpm -qa?
  • The reason for the question
    • Troubleshooting and debugging
    • Vulnerability scanning; application whitelisting
    • System management, inventory, accounting, entitlements
  • Why is rpm -q not enough?
    • dpkg-query -W -f='${binary:Package} ${Version}\n'
    • .zip/.jar Java applications, single static binary in a container image
    • Higher-level collections and products and relationships among them
  • XKCD 927, FTW!

What is SWID?

  • SWID stands for Software Identification
  • ISO/IEC 19770-2:2015 standard
    • Text is not available free of charge
    • But you are not missing much
    • It mostly just describes XML schema for XML namespace
  • Quiz: Where would you look for that XML schema definition?

XML schema definition

  • xsi:schemaLocation=""
  • It includes decent xs:documentation, containing most of the facts from the ISO standard
  • XML file with <SoftwareIdentity /> root element in SWID XML namespace shall be called SWID tag
    • Primary purpose is to describe installed software
    • And relationships
    • Also distribution/installation media (corpus tags)

Example SWID tag for distribution

  • /usr/lib/swidtag/
<?xml version="1.0" encoding="utf-8"?>
  tagId="org.fedoraproject.Fedora-29" tagVersion="1"
  name="Fedora" version="29" versionScheme="unknown" media="(OS:linux)">
  <Entity name="Fedora Project" regid=""
                    role="tagCreator softwareCreator aggregator distributor licensor" />
  <Link rel="license" href="" />
  <Meta product="Fedora" colloquialVersion="29"
    summary="Linux distribution developed by the community-supported Fedora Project and sponsored by Red Hat, Inc."
    unspscCode="43233004" unspscVersion="20.0601" />

Possible SWID tag for package

<SoftwareIdentity xmlns=""
  xsi:schemaLocation="" xml:lang="en-US"
    name="bash" tagId="org.fedoraproject.bash-4.4.23-5.fc29.x86_64"
    version="4.4.23-5.fc29.x86_64" versionScheme="rpm">
  <Entity name="Fedora Project" regid="" role="tagCreator softwareCreator"/>
  <Meta product="bash" colloquialVersion="4.4.23" revision="5.fc29" arch="x86_64"
    summary="The GNU Bourne Again shell"/>
  <Payload n8060:pathSeparator="/" n8060:envVarPrefix="$" n8060:envVarSuffix="">
    <File size="312" name=".bashrc" location="/etc/skel" n8060:mutable="true" key="true"
    <File size="33" name="alias" location="/usr/bin" key="true"
    <File size="1190216" name="bash" location="/usr/bin" key="true"

Additional XML namespaces

  • xsi:schemaLocation=""
      • Practical steps for implementing SWID tags
      • Still some missing areas, sometimes internally contradicting

Let's make a SWID tag

# dnf copr enable adelton/swid
# dnf install -y rpm2swidtag
# rpm2swidtag glibc
<?xml version="1.0" encoding="utf-8"?>
<SoftwareIdentity xmlns="" xmlns:sha256="" xmlns:n8060="" xmlns:xsi="" xsi:schemaLocation="" xml:lang="en-US"
  name="glibc" tagId="unavailable.invalid.glibc-2.28-26.fc29.x86_64"
  version="2.28-26.fc29.x86_64" versionScheme="rpm">
  <Entity name="" regid="invalid.unavailable" role="tagCreator"/>
  <Entity name="Fedora Project" regid="" role="softwareCreator"/>
  <Meta product="glibc" colloquialVersion="2.28" revision="26.fc29" arch="x86_64"
    summary="The GNU libc libraries"/>
  <Evidence date="2019-01-26T12:05:22Z" deviceId="" n8060:pathSeparator="/" n8060:envVarPrefix="$" n8060:envVarSuffix="">
    <File size="0" name="gai.conf" location="/etc" n8060:mutable="true"/>
    <File size="0" name="" location="/etc" n8060:mutable="true"/>
    <File size="28" name="" location="/etc"
      n8060:mutable="true" key="true"/>
    <Directory name="" location="/etc"/>
    <File size="1498" name="nsswitch.conf" location="/etc"

Any SWID tags around?

  • After all, I have software installed on my Fedora machine
# swidq -a
org.fedoraproject.Fedora-29 /usr/lib/swidtag/
+ org.fedoraproject.Fedora-29-Container /usr/lib/swidtag/
  • But we can generate SWID tag inventory for installed rpms
# dnf rpm2swidtag regen
# swidq -a
[ ... try it and see ... ]
  • Changes from subsequent DNF operations on rpms will be reflected
  • The rpm2swidtag --repo ... can generate swidtags data for YUM/DNF repository
    • DNF rpm2swidtag plugin can deploy SWID tags from swidtags repository metadata upon package installations

XML is hard (on eyes)

  • How do you make sense of that XML content?
$ swidq -i -n Fedora
Tag id               [org.fedoraproject.Fedora-29]
Tag version          [1]
File                 [/usr/lib/swidtag/]
Name                 [Fedora]
Version              [29] version scheme [unknown]
Colloquial version   [29]
XML language         [en-US]
Edition              [Container] (+)
Product              [Fedora]
Entitlement required [false]
Summary              [Linux distribution developed by the community-supported Fedora Project and sponsored by Red Hat, Inc.]
United Nations Standard Products and Services Code [43233004]
Media                [(OS:linux)]
Entity [tagCreator softwareCreator aggregator distributor licensor] regid []
                                                                     name [Fedora Project]
Link [license] to []
Link [component] to [swid:com.example.test.mailcap-2.1.48-4.fc29.noarch] (*)
Link [component] to [swid:com.example.test.mutt-5:1.10.1-1.fc29.x86_64] (*)
$ swidq -i -n mutt
Tag id                [com.example.test.mutt-5:1.10.1-1.fc29.x86_64]
File                  [/var/lib/swidtag/rpm2swidtag-generated/com.example.test.mutt-5:1.10.1-1.fc29.x86_64.swidtag]
Name                  [mutt]
Version               [5:1.10.1-1.fc29.x86_64] version scheme [rpm]
Colloquial version    [1.10.1]
Revision              [1.fc29]
Architecture          [x86_64]
RPM resource          [mutt-5:1.10.1-1.fc29.x86_64]
Entity [tagCreator] regid [] name []
Entity [softwareCreator] regid [] name [Fedora Project]
Evidence gathered at [2019-01-26T12:08:15Z] from []
Tag id                [com.example.test.mutt-5:1.10.1-1.fc29.x86_64-component-of-org.fedoraproject.Fedora-29]
Tag is supplemental
Supplemental to       [swid:org.fedoraproject.Fedora-29]
File                  [/var/lib/swidtag/rpm2swidtag-generated/com.example.test.mutt-5:1.10.1-1.fc29.x86_64-component-of-org.fedoraproject.Fedora-29.swidtag]
Name                  [mutt]
Entity [tagCreator] regid [] name []
Entity [softwareCreator] regid [] name [Fedora Project]
Link [component] to [swid:com.example.test.mutt-5:1.10.1-1.fc29.x86_64]

Some implementation notes

  • The @tagId could be just UUID but I like to know what I'm looking at
    • On the other hand, the attribute value should bear no semantics
  • Tag creator vs. software creator
  • We use @arch for architecture (<xs:anyAttribute processContents="lax"/>)
  • Link elements can reference other SWID tags, as well as generic URIs
    • Used for relationships
    • Should package point to higher-level component, or vice versa?
  • Special relationship type is supplemental, for amending other tag(s)
    • Powerful but potentially confusing
    • Is the @name value from the com.example.test.mutt-5:1.10.1-1.fc29.x86_64-component-of-org.fedoraproject.Fedora-29 example correct?

Listing SWID tags on system

  • The standard and NIST IR 8060 assume /swidtag or
    # find / -name '*.swidtag'
  • To be reasonably efficient, we propose
    • Entries in /etc/swid/swidtags.d are symlinks to directories where .swidtag files are expected to live
    • With the goal of supporting non-rpm (.zip, .jar) installations easily
      • While not scanning all the disks to list SWID tags on system
    • This is where swidq looks
      • But -p can point it to any location

Signed SWID tags

  • Enveloped XML signatures
    • rpm2swidtag's --sign-pem ... option invokes xmlsec1 --sign ...
  •'s seem to require full secure-timestamped XAdES-T signatures
    • But what will be the root of trust?
  • We propose /etc/pki/swid/CA/<tag-creator-regid> as location for CA certificates for local validation
    • Scanning tools can of course use their own trust database
    • Red Hat published its code signing key at

Near-term plans

  • The XML namespace for the DNF/YUM repository swidtags metadata
  • Publishing our practices (like the use of /etc/swid/swidtags.d or supplemental component) in repo under
    • To make discussion easy, via issues or pull requests
  • Implementing libdnf plugin as well
  • Getting the tools (rpm2swidtag and plugins, swidq) to Fedora 30
  • Signature validation, probably in swidq
  • Relationship tree display, probably in swidq
  • Fetching SWID tags from YUM/DNF repo metadata for already installed packages

Welcoming contributions

  • Opinions of people who looked at SWID are valuable
    • Really, we'd love to discuss the details with people with strong opinions
      • Should the @tagId for rpms be NEVRA or NEVRA.rpm?
      • The use of @arch
      • Symlinks in Payload/Evidence, file ownership and mode
      • Our use of Resource for rpm and rpm-signature types
      • ...
  • Real-life use-cases
  • Extending the tools to produce SWID tags for other package formats, including .zip or unpacked directories


  • Repo documenting practices, under (to be created)