Notary Documentation

repository·master·Indexed 25 days ago

https://github.com/notaryproject/notary

Notary is an implementation of The Update Framework (TUF) specification, providing a client and server to enable secure software distribution. It is widely used in Docker Content Trust (DCT) to ensure content integrity and freshness. Key features include survivable key compromise, freshness guarantees via timestamping, configurable trust thresholds, and signing delegation.

Tokens
20.5K
Snippets
31
Records
153
Agent score
84%

What's inside Notary

  1. Overview of Notary

    master

    Notary is an implementation of The Update Framework (TUF) specification. It provides a client and a server for running and interacting with trusted collections of content.

    Key features include:

    • Survivable Key Compromise: Uses a hierarchy of keys to ensure that the loss of a single key (except the root role) does not compromise the entire system.
    • Freshness Guarantees: Uses timestamping to prevent replay attacks where old signed payloads are presented as current.
    • Configurable Trust Thresholds: Allows requiring multiple signatures on content to increase security.
    • Signing Delegation: Enables publishers to delegate parts of their collection to other signers via signed metadata.
    • Distribution Agnostic: Trust guarantees are not tied to specific delivery channels; metadata can be mirrored via any channel.
  2. Understand the Notary service architecture

    master

    The Notary service architecture is composed of three primary components that interact to provide secure metadata management based on The Update Framework (TUF).

    Core Components

    • Notary Client: Pulls or pushes TUF metadata to/from Notary services. Clients are responsible for generating and signing the root, targets, and sometimes snapshot metadata.
    • Notary Server: Acts as the central repository for trusted collections. It stores and serves signed TUF metadata in a database. It is responsible for validating uploaded metadata, generating timestamp (and sometimes snapshot) metadata, and ensuring metadata consistency.
    • Notary Signer: A specialized component that stores private signing keys (wrapped and encrypted using JOSE) in a separate database from the server. It performs signing operations on demand when requested by the Notary server.

    Key Responsibilities

    ComponentPrimary Responsibility
    ClientGenerates/signs root, targets, snapshot metadata; uploads to server.
    ServerValidates uploads; generates timestamp/snapshot metadata; serves metadata to clients.
    SignerSecurely stores private keys; performs cryptographic signing operations.
  3. Understand the Notary threat model

    master

    The Notary architecture is designed to mitigate various compromise scenarios involving the Notary server, the Notary signer, and client-side keys. The security of the system depends on the separation of concerns between the server (which holds the timestamp key), the signer (which holds snapshot and timestamp private keys), and the clients (who hold root, targets, and delegation keys).

    Key attack vectors include:

    • Notary Server Compromise: Attackers can cause Denial of Service (DoS) or serve malicious metadata to new clients who have no pinned trust. However, they cannot compromise timestamp or snapshot keys, meaning existing clients with pinned trust will detect the attack.
    • Notary Signer Compromise: Attackers may gain access to snapshot and timestamp private keys. If keys are stored in a database, they can be exfiltrated; if in an HSM, they can be used to sign arbitrary content but not exfiltrated.
    • Client Key Compromise: The impact depends on which keys are lost (e.g., Root, Targets, Snapshot, or Delegation keys) and whether the attacker also possesses Notary Service write-capable credentials.
  4. Reload Notary Signer logging level via signals

    master

    On Linux and OSX, you can dynamically change the logging level of a running notary-signer process using signals without restarting the service.

    • Increase logging level: Send SIGUSR1.
    • Decrease logging level: Send SIGUSR2.

    Note: Windows does not support dynamic logging level changes via signals.

  5. Import and export Notary keys

    master

    You can import PEM-formatted keys or export existing encrypted keys.

    Importing: notary key import <pemfile> --role <key_role> --gun <key_gun>

    • If --role or --gun are omitted, Notary assumes a delegation role.
    • Multiple keys in one PEM file are supported.

    Exporting:

    • All keys: notary key export -o <file.pem>
    • By Key ID: notary key export --key <keyID> -o <file.pem>
    • By GUN: notary key export --gun <GUN> -o <file.pem>
  6. Initialize a trusted collection

    master

    Use notary init <GUN> to initialize a trusted collection. This generates local targets and snapshot keys. If no root key is found in the client cache, Notary will generate one. You will be prompted for a passphrase to encrypt the keys at rest.

    To use an existing encrypted root key, use the --rootkey flag.

    Note: After initialization, you must run notary publish <GUN> for the changes to take effect on the server.

  7. Rotate Notary keys

    master

    Use the notary key rotate command to rotate keys in case of compromise.

    • Root and Targets keys: Must be locally managed. Rotate using notary key rotate <role> (without the -r flag).
    • Snapshot key: Can be rotated to the server so the server signs snapshots. This is useful for delegation workflows. Use notary key rotate snapshot -r.
    • Timestamp key: Must be remotely managed. Use notary key rotate <GUN> timestamp -r.
  8. Manage Notary Signer encryption passphrases via environment variables

    master

    Notary signer uses environment variables to encrypt and decrypt private keys. The passphrase for a specific alias must be provided as NOTARY_SIGNER_<ALIAS_NAME>.

    To rotate the passphrase for new keys without losing access to old keys:

    1. Set a new default_alias in the storage section (e.g., passwordalias2).
    2. Export the old passphrase using the old alias name.
    3. Export the new passphrase using the new alias name.

    Example: If default_alias is passwordalias2, and you want to transition from passwordalias1:

    export NOTARY_SIGNER_PASSWORDALIAS1=mypassword
    export NOTARY_SIGNER_PASSWORDALIAS2=mynewfancypassword
  9. Use delegations with Docker Content Trust

    master

    Docker Engine (1.10+) supports using the targets/releases delegation as the canonical source for trusted image tags.

    Pulling Images

    • Docker 1.10: Docker searches targets/releases for the signed tag and falls back to the targets role if not found.
    • Docker 1.11+: docker pull commands with Content Trust enabled will only pull tags signed by the targets/releases delegation role or the targets base role.

    Pushing Images

    • Docker 1.10: Attempts to sign and push with targets/releases if it exists, otherwise falls back to targets.
    • Docker 1.11+: Attempts to sign and push with all delegation roles directly under targets (e.g., targets/role, but not nested roles like targets/nested/role) for which the user has signing keys. If delegation roles exist but the user lacks keys, the push fails. If no delegation roles exist, it falls back to the targets role.

    Setup Requirement

    To use targets/releases for pushing and pulling, you must add and publish the delegation role using Notary. When adding the delegation, use the --all-paths flag to allow signing all tags.

  10. Set up the Notary CLI

    master

    To use the Notary CLI, you must specify the Notary server URL using the -s flag and a directory for private keys and cache using the -d flag.

    When working with Docker Content Trust, it is recommended to set the client cache directory to ~/.docker/trust.

    You can simplify usage by creating a shell alias to include these flags automatically.

  11. Manage Notary key roles and security priorities

    master

    Notary uses five primary key roles with varying levels of criticality. When managing your repository, prioritize the security of the Root key above all others. The hierarchy of importance (from most to least critical) is:

    1. Root: Anchors all trust. Compromise is catastrophic and requires special rotation mechanisms.
    2. Targets: Responsible for all Delegations permitted to sign content.
    3. Delegations: Allows specific users/systems to sign content in subtrees.
    4. Snapshot: Provides a consistent view of the repository state.
    5. Timestamp: Ensures freshness and prevents replay attacks.

    Security Recommendations:

    • Timestamp Key: Must be managed by the server due to high frequency of expiration.
    • Snapshot Key: Can be managed by the server (default in Docker Content Trust) or by the user. If using Delegations for collaboration, allow the server to sign snapshots.
    • Targets and Delegations Keys: These are high-value targets as they allow signing arbitrary content. They are often stored on personal computers but should be protected using the Notary client's password-based AES 256 encryption.