Skip to content

docs: add architecture overview - #1360

Open
Tatsinnit wants to merge 2 commits into
notaryproject:mainfrom
Tatsinnit:docs/architecture-overview
Open

docs: add architecture overview#1360
Tatsinnit wants to merge 2 commits into
notaryproject:mainfrom
Tatsinnit:docs/architecture-overview

Conversation

@Tatsinnit

Copy link
Copy Markdown
Contributor

Description

Adds ARCHITECTURE.md — a contributor-facing map of the codebase that explicitly correlates this CLI with the wider Notary Project — and links it from README.md and building.md.

This is documentation only: no source, CLI, dependency, or Go-version changes.

Context: this was originally part of #1359 alongside the golangci-lint tooling. Per review feedback there, it has been split into this standalone PR so the doc gets its own focused review and the lint change can land independently.

What's in the document

Section Purpose
Where Notation Sits in the Notary Project Diagram + table showing how this CLI relates to notaryproject/specifications and to notation-go, notation-core-go, notation-plugin-framework-go, tspclient-go and oras-go, with the exact versions pinned in go.mod
Specification Map Table linking each Notary Project specification to the parts of the CLI it governs
Design Philosophy The four principles the layout reflects (thin CLI, centralized registry plumbing, two internal/ trees, pluggability)
High-Level Architecture The CLI → CLI-internal → shared utils / external libraries layering
Core Workflows runSign and runVerify end-to-end flows
Trust Model The three on-disk artifacts (trust store, trust policy, signing keys) and how signing scheme selects a store type
Signature Storage in OCI Registries How signatures are stored as referrers of the signed artifact, and why they travel with it
Plugin Extensibility How a KMS/HSM-backed signing plugin is invoked
Developer Workflow Makefile targets, version injection, CI/CD pipeline
User-Facing CLI Workflows Copy-pasteable sign/verify, blob, and plugin flows

Principles I tried to follow

These came directly out of the review discussion on #1359 — thank you @shizhMSFT for the steer:

  • The specifications are the source of truth. This is stated up front and again in the Trust Model section. The document describes how this CLI is assembled and where it delegates; it deliberately does not restate normative behaviour.
  • No package/symbol tables. Those belong in godoc, which is always current. The doc points at go doc ./... / pkg.go.dev instead, so it can't drift into being wrong.
  • Architectural altitude only, so the maintenance burden stays low. The closing note asks contributors to update it when command wiring or high-level structure changes.
  • Mermaid throughout (8 diagrams), colour-coded by layer. Each one was rendered and visually checked before pushing rather than trusting that the syntax parses.
  • No word wrapping, per the markdown preference raised in review.
  • No "improvement opportunities" / roadmap content — that belongs in issues or the roadmap, not in an architecture doc.

Thoughts and open questions for the team

I'd genuinely value opinions on these — happy to take it in whatever direction the maintainers prefer:

  1. Altitude. Is this the right level of detail, or would you prefer it even thinner (say, just the layering diagram + spec map) so there is less to keep in sync?
  2. Spec map accuracy. The Specification Map asserts which spec governs which command surface. I'd appreciate a sanity check from someone closer to the specs — particularly the signing-scheme row and the trust store identity types.
  3. Pinned pseudo-versions. I noted that notation-go and tspclient-go are pinned to untagged commits. Useful context for newcomers, or noise that will go stale? Happy to drop it.
  4. Keeping it current. Would a lightweight CI check help (for example, failing if cmd/notation/main.go changes without ARCHITECTURE.md being touched), or is that more friction than it's worth?
  5. Placement. Repo root alongside building.md seemed natural, but I'm happy to move it under specs/ or docs/ if that fits the repo's conventions better.
  6. Audience. I wrote this for a new contributor trying to find their way around. If the more valuable audience is integrators consuming the libraries, I can re-angle it.

Please treat every section as negotiable — I'm very happy to cut, reshape, or rewrite based on what the team finds useful. 🙏

Signed commits ✅

Add ARCHITECTURE.md, a contributor-facing map of the codebase that
correlates this CLI with the wider Notary Project:

- Where notation sits relative to notaryproject/specifications and the
  notation-go / notation-core-go / tspclient-go / plugin-framework
  libraries, with the exact versions pinned in go.mod.
- A specification map linking each Notary Project spec to the parts of
  the CLI it governs.
- Mermaid diagrams for the layering, sign/verify workflows, trust model,
  OCI signature storage (referrers), plugin invocation, and CI/CD.

The specifications remain the source of truth; this document is a map
for contributors, not a restatement of normative behaviour. Package- and
symbol-level detail is deliberately left to godoc so the doc does not
drift from the code.

Link it from README.md and building.md.

Signed-off-by: Tatsat Mishra <tamishra@microsoft.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a contributor-facing architecture map for the Notation CLI, and links to it from existing contributor documentation, to help new contributors understand how this repo relates to the wider Notary Project.

Changes:

  • Add ARCHITECTURE.md with an overview of project layering, key workflows, trust model, and related Notary Project specs/libraries.
  • Link ARCHITECTURE.md from README.md (contributing section) and building.md (developer onboarding).

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
README.md Adds a link to the new architecture overview doc for contributors.
building.md Adds a pointer to ARCHITECTURE.md for readers who want codebase orientation.
ARCHITECTURE.md Introduces a comprehensive architecture overview (diagrams, spec map, workflows, dev workflow).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ARCHITECTURE.md Outdated
Comment thread ARCHITECTURE.md Outdated
Comment thread ARCHITECTURE.md Outdated
@codecov

codecov Bot commented Aug 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 79.09%. Comparing base (51ff5ec) to head (73ad053).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #1360   +/-   ##
=======================================
  Coverage   79.09%   79.09%           
=======================================
  Files          68       68           
  Lines        3076     3076           
=======================================
  Hits         2433     2433           
  Misses        436      436           
  Partials      207      207           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

- Signing keys live in signingkeys.json with key material under
  localkeys/, not config.json. Confirmed against dir.PathSigningKeys
  and dir.LocalKeysDir in notation-go.
- Fully qualify notation.BlobVerifier to match notation.BlobSigner.
- Prefix fix-line-endings with 'make' for consistency with the other
  entries in the table.

Signed-off-by: Tatsat Mishra <tamishra@microsoft.com>

@shizhMSFT shizhMSFT left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The doc should be non-verbose, simplified, and de-duplicated.

Comment thread ARCHITECTURE.md
Comment on lines +30 to +37
SPEC("<b>notaryproject/specifications</b><br/>normative behaviour<br/>signature · trust policy · workflows · plugins")
CLI("<b>notation</b> (this repo)<br/>Cobra CLI · flags · output rendering")
NG("<b>notation-go</b><br/>signer · verifier · trust policy<br/>trust store · plugin manager · registry")
NCG("<b>notation-core-go</b><br/>signature envelopes (JWS · COSE)<br/>x509 · revocation (CRL/OCSP)")
TSP("<b>tspclient-go</b><br/>RFC 3161 timestamping")
PFW("<b>notation-plugin-framework-go</b><br/>plugin contract")
ORAS("<b>oras-go/v2</b><br/>OCI registry & OCI-layout I/O")
PLUGIN("Third-party plugins<br/>KMS / HSM signing binaries")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider remove descriptions like "normative behaviour signature · trust policy · workflows · plugins" as they are too verbose for a diagram.

Comment thread ARCHITECTURE.md
Comment on lines +59 to +65
| Dependency | Version in [`go.mod`](go.mod) | Role |
|---|---|---|
| [`notation-go`](https://github.com/notaryproject/notation-go) | `v1.2.0-beta.1.0.20250512015818-2bc67e7695ef` | Signing/verification engine, trust policy & trust store evaluation, plugin manager, registry glue |
| [`notation-core-go`](https://github.com/notaryproject/notation-core-go) | `v1.3.0` | Signature envelope generation/parsing (JWS, COSE), certificate chain validation, CRL/OCSP revocation |
| [`notation-plugin-framework-go`](https://github.com/notaryproject/notation-plugin-framework-go) | `v1.0.0` | Contract shared with out-of-process plugin binaries |
| [`tspclient-go`](https://github.com/notaryproject/tspclient-go) | `v1.0.1-0.20250306063739-4f55b14d9f01` | RFC 3161 Time-Stamp Protocol client |
| [`oras-go/v2`](https://oras.land) | `v2.6.0` | OCI registry client, registry auth, OCI image layout I/O |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to remove versions as they are not tracked by dependabot in markdown files..

Comment thread ARCHITECTURE.md
Comment on lines +91 to +113
## High-Level Architecture

```mermaid
flowchart TD
A("CLI layer<br/><b>cmd/notation/</b><br/>sign · verify · list · inspect · login · key<br/>+ blob/ · cert/ · plugin/ · policy/")
B("CLI-internal<br/><b>cmd/notation/internal/</b><br/>flag · display · sign · verify<br/>truststore · experimental · errors · plugin")
C("Shared utilities<br/><b>internal/</b><br/>auth · config · envelope<br/>httputil · revocation · x509")
D("External Notary libraries<br/>notation-go · notation-core-go · oras-go")

A -->|"delegates to"| B
B -->|"built on"| C
B -->|"calls"| D

classDef cli fill:#dbeafe,stroke:#1d4ed8,stroke-width:1.5px,color:#1e3a8a;
classDef internal fill:#fef3c7,stroke:#b45309,stroke-width:1.5px,color:#78350f;
classDef utils fill:#dcfce7,stroke:#15803d,stroke-width:1.5px,color:#14532d;
classDef libs fill:#f3e8ff,stroke:#7e22ce,stroke-width:1.5px,color:#581c87;

class A cli
class B internal
class C utils
class D libs
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section duplicates the section "Where Notation Sits in the Notary Project".

Comment thread ARCHITECTURE.md
Comment on lines +117 to +148
### Signing (`runSign`, [`cmd/notation/sign.go`](cmd/notation/sign.go))

```mermaid
flowchart LR
A("GetSigner<br/>local key or plugin") --> B("getRepository<br/>registry or OCI layout")
B --> C("prepareSigningOpts<br/>envelope · expiry · TSA · revocation")
C --> D("resolveReference<br/>tag → digest")
D --> E("notation.SignOCI<br/>pushes signature as OCI referrer")

classDef step fill:#dbeafe,stroke:#1d4ed8,stroke-width:1.5px,color:#1e3a8a;
class A,B,C,D,E step
```

Signing always resolves a tag to an immutable digest first, so a signature is bound to specific content rather than a movable tag.

### Verification (`runVerify`, [`cmd/notation/verify.go`](cmd/notation/verify.go))

```mermaid
flowchart LR
A("GetVerifier<br/>trust store · trust policy<br/>revocation · plugins") --> B("getRepository +<br/>resolveReference")
B --> C("notation.Verify")
C -->|"failure"| D("ComposeVerification<br/>FailurePrintout")
C --> E("display handler<br/>tree · json · text")
D --> E

classDef step fill:#dcfce7,stroke:#15803d,stroke-width:1.5px,color:#14532d;
classDef fail fill:#fee2e2,stroke:#b91c1c,stroke-width:1.5px,color:#7f1d1d;
class A,B,C,E step
class D fail
```

Blob commands mirror both flows using `notation.BlobSigner` / `notation.BlobVerifier` against local files instead of a registry.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Remove verbose descriptions for diagrams.

Comment thread ARCHITECTURE.md
Comment on lines +156 to +172
```mermaid
flowchart TD
CFG("Notation config directory")
TS("<b>Trust store</b><br/>truststore/x509/{ca,signingAuthority,tsa}/&lt;store&gt;/<br/>managed by <code>notation cert</code>")
TP("<b>Trust policy</b><br/>trustpolicy.oci.json · trustpolicy.blob.json<br/>managed by <code>notation policy</code> / <code>notation blob policy</code>")
KEY("<b>Signing keys</b><br/>signingkeys.json + localkeys/<br/>managed by <code>notation key</code>")

CFG --> TS
CFG --> TP
CFG --> KEY
TP -->|"selects"| TS

classDef root fill:#e0e7ff,stroke:#4338ca,stroke-width:2px,color:#312e81;
classDef leaf fill:#dcfce7,stroke:#15803d,stroke-width:1.5px,color:#14532d;
class CFG root
class TS,TP,KEY leaf
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here. Remove verbose descriptions for diagrams.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants