To sign TeamCity artifacts, create a detached signature for each file in the build, keep the signing key out of reach of ordinary build steps, publish a provenance record next to the artifact, and make deployment verify both. SLSA calls the strong version of this Build L3.
What does "provenance" actually mean here?
SLSA defines provenance as a description of "what entity built the artifact, what process they used, and what the inputs were." That is a record, not a guarantee. A consumer reads it and decides whether the build looks like the one they expected.
The SLSA levels build up in a clear order. At Build L1 provenance simply exists, and it may be unsigned or incomplete. At Build L2 a hosted build platform generates and signs it, on dedicated infrastructure and not on someone's workstation. At Build L3 the platform must also keep the signing secret away from user-defined build steps and stop one run from influencing another.
The page we read is marked retired in favour of a newer spec version, so check the current text before you cite a level in an audit.
Where does TeamCity fit?
Here is the honest gap. In the TeamCity documentation page we read, we found password parameters and remote secrets, but nothing about native provenance generation or signing. We did not confirm whether your TeamCity version produces provenance on its own. Treat that as something to check in the JetBrains docs for your version, and assume you will wire signing in yourself.
What the docs do confirm is how to keep a secret out of sight. A password parameter hides a value from both the TeamCity UI and build logs. For stronger handling you can create a remote secret parameter, which holds a query rather than a value and resolves it when needed. The page names HashiCorp Vault as the only supported remote secret storage.
How do you sign a file in a build step?
Cosign can sign any file. The Sigstore docs show the key-based form:
cosign sign-blob --yes --key cosign.key --bundle bundle.sigstore.json app.tar.gz
The bundle holds the signature and the material needed to verify it. The docs say to store it, because verification needs it. The --yes flag skips prompts, which is what you want on an agent with no terminal.
Keyless signing is the recommended mode in the same docs: an ephemeral key tied to an OpenID Connect identity. That needs your CI to hand the job an identity token. We did not confirm that TeamCity offers one, so the key-based form is the safer plan to document for now.
How do you keep the key away from build steps?
This is the difference between L2 and L3, and it is the part most teams skip.
If the key sits in a parameter that any build step can read, anyone who can edit the build configuration can sign anything. A constructed example: a contributor adds a step to a feature branch that runs your signing command on a binary they built by hand. The signature is valid, and it means nothing.
Better options, in order of effort:
- Sign in a separate, locked build configuration that only runs from a protected branch or tag, and keep the key parameter only there.
- Pull the key from a vault at the moment of signing, not at agent start.
- Move signing to a service the build calls, so the build never holds the key at all.
What to do
- Pick the artifacts that matter (installers, container images, release archives) and list them.
- Write a short provenance file per release: source commit, build configuration ID, build number, builder, and the digest of each output.
- Sign artifact and provenance together with Cosign and keep the bundle beside them.
- Store the key as a password parameter at minimum, and a Vault-backed remote secret if you run Vault.
- Restrict who can edit the signing configuration, and review changes to it like production code.
- Make the deploy step verify the signature and check that the recorded commit is one you expect.
- Rotate the key on a schedule and after any suspected exposure.
Safeguard can scan the dependencies that go into the build and apply policies and gates before release, which covers the inputs that provenance records but cannot judge. Signing covers the output.
Quick check
Does a valid signature mean the artifact is safe?
No. It shows who signed it and that it was not changed afterwards. It says nothing about whether the code inside is free of flaws or malicious content.
What is the difference between SLSA Build L2 and L3?
At L2 a hosted platform generates and signs provenance. At L3 the platform also prevents the signing secret from being reachable by user-defined build steps and isolates runs from one another.
Sources
- SLSA specification v1.0, build levels (fetched 18 October 2026)
- Sigstore Cosign: signing blobs and files (fetched 18 October 2026)
- JetBrains TeamCity: configuring build parameters (fetched 18 October 2026)
Last reviewed: 18 October 2026.