Okay, I think we're good.
Okay, hi everyone.
Welcome to our presentation, enhancing swift supply chain security,
build time S bomb generation and swift package manager.
We'll start with some introductions.
My name is Ed.
I'm a software engineer at Apple focused on software supply chain security.
And I'm based in Seattle, Washington, in the United States.
Hi, I'm Sam.
I'm a software developer at Apple.
And I'm work on swift package manager and core builds.
I'm based in Ottawa, Canada.
Okay.
In this presentation, we'll discuss the role of S bombs
in securing swift supply chain and explain why it's hard to create swift
S bombs with existing tools.
We'll provide a brief demo of our upcoming future
by integrates S bomb generation into swift PM to create swift S bombs.
And we'll detail some channels where you can provide feedback
before the features released.
Sam is going to get us started by talking about swift and swift
PM fundamentals, which will provide the necessary back on concepts
that are crucial for understanding the independent S bomb feature.
Thanks, Ed.
So swift is a multi-platform programming language.
It is a versatile language as it scales from embedded devices.
And kernels to apps and cloud infrastructure.
It's also fast, expressive, and safe.
And has unmatched interoperability with C and C++.
And has interoperability support with Java using either
January or modern FFI.
Here's a fun fact about swift.
Two months ago on December 3, 2025, swift mark
it's ten year anniversary of being open source.
Swift package manager, also known as Swift PM, is available
with the Swift 2 chain.
Swift package manager is a developer tool that allows
a developer to build, test, document, and run the code by managing
the distribution of Swift code, including dependency management
and a form of a Swift package.
It also allows for easily importing other Swift packages into the application
and executable or library, making it an essential part of a Swift
developer's tools box.
All of the Swift package can define products which can be consumed by other packages.
Swift PM organizes code through several logical units.
Packages, products, and targets.
We will only focus on packages and products as they are important concepts
for Swift S1.
A Swift package is a reusable component that can be distributed
to other Swift projects.
It consists of a package manifest or package the Swift manifest file
along with source files, resources, and other assets.
Here's an example of three packages.
Swift example, Swift crypto, and Swift S1.
Package level dependencies relate packages to packages.
In this example, Swift example depends on Swift crypto,
and the Swift crypto package depends on Swift S1 package.
A Swift PM product is the consumable artifacts produced and exposed by Swift package.
Said differently, a Swift package can produce a zero or more products.
A Swift PM product can be a library, an executable or a plugin.
There are packets to product relationships where packages produce products.
For this presentation, we're classifying that relationship as a dependency type.
For example, each of these packages produces products.
This Swift example package produces a product called Swift example product.
Sorry, naming this hard.
Swift crypto package produces two products, Swift crypto and crypto extras.
And the Swift Sn package produces a product named Swift S1.
Products can also depend on each other.
These are known as product level dependencies.
The Swift example product depends on the crypto product in another package.
And the crypto extras product depends on Swift Sn1 product.
So to recap, there are three types of dependencies.
Package level dependencies, which were a package depends on another package.
Package to product dependencies, where a package depends on other products it produces.
And product level dependencies were products depend on another product.
So we know what packages and products are.
Let's do mouth and talk about how Swift PM builds a Swift project.
And Swift PM goes through several stages to build a product.
And the two stages that are relevant as one integration feature are the package methods loading and build execution.
The green package manifest loading Swift PM performs package resolution resolution, which determines the package dependencies and the versions to use.
And also creates a module's package graph representing the package and product dependency tree.
The build execution stage comes next.
Swift PM has several built systems, but we'll be focusing on the Swift build build system.
The Swift build build system, not to be confused with the Swift build command line tool, is currently under evaluation.
And there's the build engine that's used behind Xcode.
Swift PM dedicates build activities to the Swift build build system.
And as part of those activities, Swift build, computes and produces a build dependency graph.
The build dependency graph consumes the result modures graph from the package manifest loading stage.
The result modures graph is an output of the package manifest loading stage.
And the Swift build dependency graph is an output of the build execution stage.
The graphs contain different information.
Oh, sorry to me, second here.
The result modures graph includes the information that is beneficial for S-bomb, like all package and product and dependency tree,
including extraneous components, package level dependencies, product to product dependencies, and product level dependencies.
On the other hand, the Swift build dependency graph is derived by converting products into the result modures graph into build targets.
The build dependency graph contains information about only the build targets using the build, and target level dependencies after converting from product level dependencies and the result modures graph.
There are two factors that can influence the result modures graph, and the Swift build dependency graph.
Traits and conditions.
Traits can be thought of something similar to feature flags, they'll not quite the same.
They're evaluated during the package manifest loading stage, and they can either include or exclude parts of the result modures graph.
Package authors can define traits for their own package, and not dependency packages, but they can decide to enable package traits through the manual package dependency traits through the manifest.
On the other hand, conditions are based on build time environmental conditions.
They're evaluated during build conditions, and they affect, and their effect essentially affects the build dependency graph generated by the Swift build system.
This is a summary table that compares the internal Swift PM graphs.
The key takeaway here is there's red and green colors on both sides of the table.
That's because the two graphs contain different information and insights about the build process, and this is important for the Swift S-bomb generation feature.
Well, how long did I off now to have who will talk about some of the challenges that existing tools face when creating Swift S-bombs, and will dive deeper into our implementation of Swift S-bomb generation with Swift PM.
Okay, thank you Sam. To start, I'll cover why Swift S-bombs are important to Swift supply chain security.
Swift S-bombs harden the security profile of Swift projects in multiple ways.
First, by understanding what software components are in the projects, Swift developers can better assess and manage the risk associated with third-party components.
This includes identifying outdated or un-maintained dependencies that could pose future risk.
Additionally, S-bomb's help promote transparency and compliance in Swift projects.
This is important when distributing Swift software to other organizations.
Swift developers can document that their software doesn't contain disclosed vulnerabilities,
while organizations can show that their compliance with security standards.
Finally, the event of a security incident, and S-bomb can speed up the process of determining which parts of a Swift application might be affected.
So S-bomb's help Swift developers remediate vulnerabilities in their projects.
We define two characteristics for good Swift S-bomb.
The first characteristic is accuracy, so for the purpose of this presentation, a Swift S-bomb is accurate when it enumerates the components that are actually present and used in the artifact.
The second characteristic we prioritize is granularity.
For the purpose of this presentation, a Swift S-bomb is granular when it reflects direct and transmitted dependencies at the package and product levels.
So this is our example diagram from the previous section. It shows package level, package to product and product level dependencies.
An accurate and granular S-bomb can model all three types of dependencies without lacking critical information or adding extra noise.
A good Swift S-bomb can be used to determine whether a disclosed vulnerability and a package affects our own package or product.
So let's say Swift example package is a monorepo, and I'm a developer who owns Swift example product.
I wake up tomorrow morning and I find out that Swift S-bomb has a new disclosed vulnerability.
As a developer, I want to know whether this vulnerability affects my product.
If I look at an accurate and granular Swift S-bomb, I can easily determine this.
My product only uses the crypto product, which has no dependencies.
That means the crypto product doesn't use Swift S-bomb and my product isn't affected.
On the other hand, any other product in the monorepo, that's using crypto extras, will be affected.
And that's because crypto extras uses Swift S-bomb.
This example shows why the granularity of a Swift S-bomb is important.
If we only look at the package level dependencies on the surface, it looks like our product is affected.
It's only when we dive deeper into the product level dependencies that we can see that our product isn't affected after all.
For an accurate and granular Swift S-bomb, direct and transitive dependencies should be represented for package level, package to product and product level dependencies.
Extraneous or unused components should not be included in the S-bomb,
and flies the enable or disabled dependencies should be safely handled.
We've talked about why it's important for S-bomb to be accurate and granular.
However, the capability to create accurate and granular Swift S-bomb is limited.
There are two main challenges that exist in S-bomb tools based on generating Swift S-bombs.
First, Swift PM encapsulates the build process and exposes limited information about components and dependencies.
Second, packages and products listed in a manifest file may or may not be used.
This depends on the build as well as optional flies that can enable or disabled dependencies.
As a result, S-bombs from existing tools can under or over represent the final Swift components in the artifact.
The first challenge is the lack of insight that existing tools have into the Swift build process.
Existing tool primarily draw information from the package to a Swift manifest file,
and to show dependencies package subcommand.
Package to a Swift is a manifest file that defines the package, its contents, and its dependencies.
So here's an example of a code snippet from the package to a Swift file.
First, we define a product, my sample product, which consists of a single build target, my sample target.
The build target describes the dependencies for the product. In this case, my sample product depends on the crypto product and the Swift crypto package.
Package to a Swift can tell us about direct dependencies, but not transitive dependencies.
So we can't tell from this code snippet how many dependencies the crypto product itself has.
The show dependencies package subcommand describes direct and transitive package dependencies.
In this package subcommand output, the Swift build package depends on the Swift driver and Swift system packages.
The show dependencies package subcommand performs package manifest loading, but does not execute the build.
So it's lacking information that's only known at the build execution stage.
This is a summary table of what information is available to existing spawn tools, based on package sub Swift manifest file,
and the show dependencies package subman, existing S1 tools can easily extract direct and transitive package dependencies, as well as direct product dependencies.
There's partial information about package to product dependencies, and there's no easy method extract information about transitive product dependencies.
The second challenge that existing tools face is that packages and products listed in a manifest file may or may not be used.
The second challenge that existing components listed in package sub Swift can be entirely unused by the package, used by the package, but unused and irrelevant to the product developer owns, or conditionally included based on flags like Swift traits and conditions.
This table summarizes the three cases I described in the first case unused components are included in the S1.
And in the third case, traits and conditions can alter which components end up in the final artifact.
Existing S1 tools don't know how to safely handle these flags to create accurate Swift S1s.
For these three cases, the generated S1 by existing S1 tools is noisy and or electrically information.
This is a summary table that challenges that existing S1 tools face.
Due to the limited information that Swift PM exposes, existing tools aren't able to represent transitive product dependencies, ignore extraneous components and handle conditional flags.
That means existing S1 tools are only able to generate partially accurate Swift S1s with package level dependencies.
To overcome these challenges, we're currently working on integrating S1 generation, directing to Swift PM's bill processes.
By integrating S1 generation directly into Swift PM, our S1 generation features able to take advantage of internal Swift PM graphs to create accurate and granular Swift S1s.
Swift PM's existing graphs already have a necessary information to generate accurate and granular Swift S1s.
By combining information from the resolve models graph and the Swift bill depends depends on your graph, we can use Swift PM to create Swift S1s.
Swift S1s created by Swift PM are unique and that they'll include the three types of dependencies discussed, we'll exclude extraneous components and we'll apply the effects of conditional flags.
Now all the stuff are designed to integrate S1 generation into Swift PM's bill process and we'll explore some examples of Swift S1s generated by Swift PM.
This is the Swift PM bill stage diagram from the previous section's presentation, and here's the pathway for S1 generation through Swift PM.
S1 generation goes through the Swift billed billed system and therefore uses both the resolve models graph and the Swift billed dependency graph to generate the S1.
The generated S1 reflects bill time conditions and excludes extraneous components.
To trigger S1 generation to build command, the user can use the dash dash S1 spec flag.
Here's an example command that generates both cyclone dx and Sbdx S1s for the root package.
This is a small demo of creating cyclone dx and Sbdx S1s on an example repo.
First the bill command builds the artifact as usual, then the S1s are created.
And then we take a peak at the S1 in this case the cyclone dx S1.
As a result of this command, the S1 that's generated is a cyclone dx or Sbdx JSON file that includes packages and products,
excludes extraneous components and factors in bill time conditions.
For the following slides, SAM and I created some visualizations of Swift Sbonds.
These visualizations aren't product Swift PM.
So for example, here's a Swift Sbom generated by Swift PM from its own repo using the Swift bill command and visualized by us.
The Sbom has around 60 components, which includes both packages and products and 350 dependencies.
Packages are represented as blue nodes and products or green nodes.
This is an example Sbom that will be exploring, a code snippet from the package that was used for this Sbom is on the right.
The package that Swift defines is Swift Sbom example package, which is marked in blue.
At the package level, the Swift Sbom example package depends on Swift crypto and arrows between blue nodes indicate package level dependencies.
Package to product dependencies or arrows going from blue nodes to green nodes.
In this case Swift Sbom example produces two products.
Example core and example CLI, which are marked in green.
Product level dependencies are arrows between green nodes.
Example core product depends on the crypto product.
This example Sbom contains the packages and products for single root package, but sometimes the developer has more specific needs.
Additional slides that can be used with the Sbom spec flag include dash dash Sbom filter to filter by packages products or both.
Sbom for specific product and a package.
The Sbom filter can be applied by adding dash dash Sbom filter to the build command.
By default, no filters are applied.
On the left is the original Sbom without any filters.
It shows both packages and products.
I've highlighted the packages in the white rectangle.
And on the right is the Sbom generated with a package filter.
This Sbom contains only packages.
This also works for products.
On the left is the original Sbom without any filters.
I've highlighted the products in the Sbom as well as the primary component.
And on the right is the Sbom filter by products only with exception of the primary component.
The Swift build command has a dash dash product flag that can be used to build a specified product.
This existing flag can be used in conjunction with the Sbom spec flag to generate Sbom's for specified product.
On the left is the Sbom for the Swift Sbom example package.
If we want the Sbom for example core, we can use the dash dash product flag to specify example core.
It should capture this portion of the graph.
And this is the resulting Sbom for example core product within the Swift Sbom example package.
This Sbom shows only the components that are relevant to the example core product.
Lastly, we're going to see how Sbom's are affected by tracing conditions.
Swift BM automatically modifies the Sbom when tracing conditions are applied during the build.
Trades are applied during the package manifests loading stage of the build.
In this package us with file, we added a trade for driver support for example CLI.
That means when the trade driver support is enabled, example CLI will depend on the Swift driver product and the Swift driver package.
To enable the trade in this case, we pass the flag dash dash traits driver support to the build.
On the left is the original Sbom without the trade enabled.
On the right is the Sbom with the trade enabled.
Because the Swift driver trait was enabled, the Sbom on the right has extra dependencies in the form of Swift driver.
Unlike traits which are applied during the package manifests loading stage, conditions can change dependencies during the build execution stage.
In this package us with file, we added a condition for example core.
As a result of this condition, the example core product will depend on the collections product from the Swift collections package when the build is running on the Mac OS operating system.
On the left side is original Sbom when the condition is in Mac, and on the right is the Sbom when the condition is met.
Because the artifact is built on Mac OS, the Sbom on the right has extra dependencies in the form of Swift collections.
The integration of Sbom generation into Swift PM allows us to generate accurate and granular Swift Sbom's.
We're able to represent package and product level dependencies, exclude extraneous components, and apply the results of tracing conditions.
Sbom generation for Swift PM is currently in the Swift evolution proposal phase.
Our release date isn't determined yet, but it will appear in a feature Swift pull chain.
Although this is an in-development feature, we do want to hear from you, we have developer pull chains available that contain Sbom support for various platforms.
This feature is currently untested on Windows, which has not to provide Windows link.
You can access these dead pull chains by downloading our slides, which are in the resources section of our talk page on the Boston website, and the links will be available until February 28.
For Mac OS and Linux, we recommend downloading the dead pull chain via command line tool like curl.
Here are some examples we provided that you can reference for downloading, extracting, and calling the dead pull chain with Sbom support.
We welcome feedback about this feature before it's released. Please provide feedback directly in person or on the Swift forums via the proposal.
And these slides, again, will be available on the Boston website. They're actually up there already, so you can access the links.
So to wrap up, we've discussed the role of Sbom's in securing the Swift supply chain.
We identified the existing Sbom tools have gaps from creating Swift Sbom's due to limited insight into Swift Pants internal processes.
Then we demonstrated a preview of our upcoming feature that integrates Sbom generation into Swift Pants build process.
Our in-development feature integrates Sbom generation into Swift Pants build process.
And it does this by leveraging Swift Pants resolve module graph and Swift builds build dependency graph.
Developers will soon be able to create accurate and granular Swift Sbom's that reflect only components that are actually used in that detailed direct and transit dependencies at the package and product levels.
This new capability in Swift Pants will provide Swift developers with a tool to better understand project dependencies, manage risks, and respond efficiently to security vulnerabilities.
This can significantly enhance the security posture of Swift projects.
Finally, at the end, we provided some channels for feedback.
Again, please take a look at our slides on the Boston website to access these links.
Your input is extremely valuable to us as we refine the feature and work towards our release.
That brings us to the end of our presentation.
Do we have time for questions?
Okay.
Yes.
Which version of SbDX are we generating?
For SbDX, we're generating 3.0.
And then for Cycle and Jx, we're generating 1.7.
Okay.
Yeah, question, blue shirt.
Okay, next, we'll also include the extraneous packages.
This is because we have to get sure that Sbom will come together in the wrong ways,
like maybe on the next or manual way.
Yeah.
So we, okay, sorry.
The question is, if you're nice to get all the extraneous components in the Sbom,
we actually provide a package subcommand that only runs package manifest loading.
So you get the entire components.
So including extraneous components.
And you don't have to run the build.
Yes.
I don't know about anything about SbDX.
But do you think any thing can be operating system in such a full-time libraries
dynamic libraries?
Will you see that traceability of supposed dependencies?
Okay.
Yeah.
So the question is, are we going to see system libraries or dialogues?
For this iteration of the feature, we're only working on SwiftPM packages and products.
For SbK's frameworks, dialogues, system libraries.
We're kind of investigating how to add those.
And they may or may not appear in future iterations of the feature.
Cool.
I think that might have been a one.