---
url: /en/guide/commit-signature-verification.md
description: >
  Explains the commit signature verification mechanism on CNB, including how to
  generate and add a GPG public key, sign commits locally, and the verification
  rules for the platform default signature (web-flow.gpg) and third-party
  official signatures (GitHub).
---
You can sign commits and tags with GPG, and CNB verifies these signatures and marks the
verification status on the repository pages. Signature verification is useful when committers
want to prove to others that the changes genuinely come from them.

## What Is Signature Verification

GPG (GNU Privacy Guard) is a signing tool based on asymmetric cryptography: you sign commits
with your **private key** and upload the corresponding **public key** to CNB. When CNB receives
a signed commit, it verifies the signature with your public key and checks whether the signing
key matches the committer email.

A commit that passes verification displays a **Verified** badge, indicating that:

* The commit was indeed signed by the holder of the corresponding private key;
* The commit was not tampered with in transit.

Unsigned commits or those that fail verification do not display the Verified badge.

## Managing GPG Public Keys

After logging in, go to `Profile Settings` → [GPG Keys](//cnb.cool/profile/gpg-keys)
to add, view, and delete public keys.

### Adding a Public Key

Click "Add GPG Key" and fill in the following:

* **Title**: An optional label for the key, for easier identification.
* **Public key content**: The public key in ASCII-armored format. It must start with
  `-----BEGIN PGP PUBLIC KEY BLOCK-----` and end with `-----END PGP PUBLIC KEY BLOCK-----`.

Once added, CNB parses and displays the key's fingerprint, associated emails, subkeys, and
expiration time.

> A public key with the same fingerprint cannot be added more than once. Always upload the
> **public key**, never the private key.

### Deleting a Public Key

After you delete a public key, it can no longer be used to verify new commits going forward.
However, **commits that were already verified are kept** and remain shown as verified.

## Generating a GPG Key and Signing Commits

If you do not yet have a GPG key, generate one locally:

```bash
# Generate a key pair; enter your name and email when prompted
gpg --full-generate-key

# List the key ID (the string after rsa4096/ on the sec line)
gpg --list-secret-keys --keyid-format=long

# Export the public key in ASCII-armored format and copy the output to CNB
gpg --armor --export <YOUR_KEY_ID>
```

After adding the exported public key to CNB, configure Git to sign with it:

```bash
# Set the signing key
git config --global user.signingkey <YOUR_KEY_ID>

# Sign a single commit
git commit -S -m "your message"

# Or sign all commits by default
git config --global commit.gpgsign true
```

> **Email must match**: The email associated with the signing key must match the `committer` /
> `tagger` email in the commit, and that email must be verified on your account; otherwise the
> commit will not be shown as verified. You can check the commit email with
> `git config --global user.email`.

## Platform Default Signature (web-flow.gpg)

Commits produced directly on CNB — for example, online edits in **Cloud Native Development**,
editing files via the web UI, merge request (MR) merges, and other commits automatically
generated by the platform — are automatically signed with the **platform default GPG key** and
shown as verified on the pages.

The platform public key can be obtained at the following URL, which can be used to verify these
signatures in other tools:

```text
https://cnb.cool/web-flow.gpg
```

> **Cross-platform note**: This public key is a platform-specific CNB key, mapped one-to-one to
> the platform's default committer email. If you push the repository to another platform (such as
> GitHub) and want these commits to also be shown as verified there, the other platform needs to
> separately import and adapt to this public key and its email; otherwise the commits are only
> shown as verified on CNB.

### Enabling or Disabling Official Signing for Cloud Native Development

You can control whether official GPG signing is enabled for commits in **Cloud Native
Development**. Go to `Profile Settings` → [Cloud Native Development](//cnb.cool/profile/workspaces)
and toggle **GPG Verification**:

* **When enabled**: The system automatically signs commits made in Cloud Native Development,
  to verify that the code comes from a trusted source.
* **When disabled**: Commits made in Cloud Native Development are no longer signed automatically,
  and those commits will not be shown as verified.

> This setting applies to your account and takes effect across all of your repositories.

## Third-Party Official Signature Verification

CNB can recognize and verify commits signed with the **official keys** of third-party platforms
such as GitHub. For example, GitHub official-signed commits produced via the GitHub web UI
that use `noreply@github.com` as the committer email will still be shown as verified
after being migrated to CNB.

## Verification Status Reference

CNB produces a verification result for each signature. Common statuses are as follows:

| Status                       | Meaning                                                                            |
|------------------------------|------------------------------------------------------------------------------------|
| `valid`                      | The signature is valid and the commit is verified                                  |
| `unsigned`                   | The commit contains no signature                                                   |
| `unknown_signature_type`     | The commit or tag contains a non-PGP signature                                     |
| `no_user`                    | The committer / tagger email is not associated with any user                       |
| `unverified_email`           | A GPG key was added, but the corresponding email is not verified                   |
| `bad_email`                  | The committer email does not match the identity of the signing key                 |
| `unknown_key`                | The signing key is not registered to any user account                              |
| `expired_key`                | The key used for signing has expired                                               |
| `not_signing_key`            | No "signing" flag was found in the key                                             |
| `malformed_signature`        | The signature is malformed and cannot be parsed                                    |
| `invalid`                    | The signature could not be cryptographically verified with the key found in it     |

## FAQ

* **Added a public key but commits still not shown as verified?** Make sure the commit email
  matches the key's associated email, the email is verified on your account, and you actually
  signed locally with `-S` or by enabling `commit.gpgsign`.
* **What if the key expires?** After renewing or replacing the key, re-export the public key and
  add it to CNB again.
