1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
|
# Trillian: General Transparency
[](https://goreportcard.com/report/github.com/google/trillian)
[](https://codecov.io/gh/google/trillian)
[](https://godoc.org/github.com/google/trillian)
[](https://transparency-dev.slack.com/)
> [!NOTE]
> Trillian is in maintenance mode.
> The next generation of transparency logs uses [Tiled APIs](ttps://c2sp.org/tlog-tiles)
> and are better supported by [Trillian Tessera](https://github.com/transparency-dev/trillian-tessera).
> We recommend that any new log operators first try Tessera.
>
> Community contributions to Trillian are still welcome, but please file an issue and/or swing by the Slack first for discussion!
- [Overview](#overview)
- [Support](#support)
- [Using the Code](#using-the-code)
- [MySQL Setup](#mysql-setup)
- [Integration Tests](#integration-tests)
- [Working on the Code](#working-on-the-code)
- [Rebuilding Generated Code](#rebuilding-generated-code)
- [Updating Dependencies](#updating-dependencies)
- [Running Codebase Checks](#running-codebase-checks)
- [Design](#design)
- [Design Overview](#design-overview)
- [Personalities](#personalities)
- [Log Mode](#log-mode)
- [Use Cases](#use-cases)
- [Certificate Transparency Log](#certificate-transparency-log)
## Overview
Trillian is an implementation of the concepts described in the
[Verifiable Data Structures](docs/papers/VerifiableDataStructures.pdf) white paper,
which in turn is an extension and generalisation of the ideas which underpin
[Certificate Transparency](https://certificate-transparency.org).
Trillian implements a [Merkle tree](https://en.wikipedia.org/wiki/Merkle_tree)
whose contents are served from a data storage layer, to allow scalability to
extremely large trees. On top of this Merkle tree, Trillian provides the
following:
- An append-only **Log** mode, analogous to the original
[Certificate Transparency](https://certificate-transparency.org) logs. In
this mode, the Merkle tree is effectively filled up from the left, giving a
*dense* Merkle tree.
Note that Trillian requires particular applications to provide their own
[personalities](#personalities) on top of the core transparent data store
functionality.
[Certificate Transparency (CT)](https://tools.ietf.org/html/rfc6962)
is the most well-known and widely deployed transparency application, and an implementation of CT as a Trillian personality is available in the
[certificate-transparency-go repo](https://github.com/google/certificate-transparency-go/blob/master/trillian).
Other examples of Trillian personalities are available in the
[trillian-examples](https://github.com/google/trillian-examples) repo.
## Support
- Mailing list: https://groups.google.com/forum/#!forum/trillian-transparency
- Slack: https://transparency-dev.slack.com/ ([invitation](https://join.slack.com/t/transparency-dev/shared_invite/zt-27pkqo21d-okUFhur7YZ0rFoJVIOPznQ))
## Using the Code
The Trillian codebase is stable and is used in production by multiple
organizations, including many large-scale
[Certificate Transparency](https://certificate.transparency.dev) log
operators.
Given this, we do not plan to add any new features to this version of Trillian,
and will try to avoid any further incompatible code and schema changes but
cannot guarantee that they will never be necessary.
The current state of feature implementation is recorded in the
[Feature implementation matrix](docs/Feature_Implementation_Matrix.md).
To build and test Trillian you need:
- Go 1.23 or later (go 1.23 matches cloudbuild, and is preferred for developers
that will be submitting PRs to this project).
To run many of the tests (and production deployment) you need:
- [MySQL](https://www.mysql.com/) or [MariaDB](https://mariadb.org/) to provide
the data storage layer; see the [MySQL Setup](#mysql-setup) section.
Note that this repository uses Go modules to manage dependencies; Go will fetch
and install them automatically upon build/test.
To fetch the code, dependencies, and build Trillian, run the following:
```bash
git clone https://github.com/google/trillian.git
cd trillian
go build ./...
```
To build slimmer Trillian binaries that only include the storage and quota
implementations that you need, consider specifying
[build tags](/storage/README.md#build-tags).
To build and run tests, use:
```bash
go test ./...
```
The repository also includes multi-process integration tests, described in the
[Integration Tests](#integration-tests) section below.
### MySQL Setup
To run Trillian's integration tests you need to have an instance of MySQL
running and configured to:
- listen on the standard MySQL port 3306 (so `mysql --host=127.0.0.1
--port=3306` connects OK)
- not require a password for the `root` user
You can then set up the [expected tables](storage/mysql/schema/storage.sql) in a
`test` database like so:
```bash
./scripts/resetdb.sh
Warning: about to destroy and reset database 'test'
Are you sure? y
> Resetting DB...
> Reset Complete
```
### Integration Tests
Trillian includes an integration test suite to confirm basic end-to-end
functionality, which can be run with:
```bash
./integration/integration_test.sh
```
This runs a multi-process test:
- A [test](integration/log_integration_test.go) that starts a Trillian server
in Log mode, together with a signer, logs many leaves, and checks they are
integrated correctly.
### Deployment
You can find instructions on how to deploy Trillian in [deployment](/deployment)
and [examples/deployment](/examples/deployment) directories.
## Working on the Code
Developers who want to make changes to the Trillian codebase need some
additional dependencies and tools, described in the following sections. The
[Cloud Build configuration](cloudbuild.yaml) and the scripts it depends on are
also a useful reference for the required tools and scripts, as it may be more
up-to-date than this document.
Anyone wanting to add a new storage and/or quota implementation should
understand how Trillian uses [build tags](/storage/README.md#build-tags).
### Rebuilding Generated Code
Some of the Trillian Go code is autogenerated from other files:
- [gRPC](http://www.grpc.io/) message structures are originally provided as
[protocol buffer](https://developers.google.com/protocol-buffers/) message
definitions. See also, https://grpc.io/docs/protoc-installation/.
- Some unit tests use mock implementations of interfaces; these are created
from the real implementations by [GoMock](https://github.com/golang/mock).
- Some enums have string-conversion methods (satisfying the `fmt.Stringer`
interface) created using the
[stringer](https://godoc.org/golang.org/x/tools/cmd/stringer) tool (`go get
golang.org/x/tools/cmd/stringer`).
Re-generating mock or protobuffer files is only needed if you're changing
the original files. The recommended way to do this is by using the Docker
image used by the Cloud Build:
```shell
docker build -f ./integration/cloudbuild/testbase/Dockerfile -t trillian-builder .
docker run -it --mount type=bind,src="$(pwd)",target=/src trillian-builder /bin/bash -c "cd /src; ./scripts/install_deps.sh; go generate -x ./..."
```
These commands first create a docker image from the Dockerfile in this repo, and
then launch a container based on this image with the local directory mounted. The
correct versions of the tools are determined using the `go.mod` file in this repo,
and these tools are installed. Finally, all of the generated files are regenerated
and Docker exits.
Alternatively, you can install the prerequisites locally:
- a series of tools, using `go install` to ensure that the versions are
compatible and tested:
```
cd $(go list -f '{{ .Dir }}' github.com/google/trillian); \
go install github.com/golang/mock/mockgen; \
go install google.golang.org/protobuf/proto; \
go install google.golang.org/protobuf/cmd/protoc-gen-go; \
go install google.golang.org/grpc/cmd/protoc-gen-go-grpc; \
go install github.com/pseudomuto/protoc-gen-doc/cmd/protoc-gen-doc; \
go install golang.org/x/tools/cmd/stringer
```
and run the following:
```bash
go generate -x ./... # hunts for //go:generate comments and runs them
```
### Updating Dependencies
The Trillian codebase uses go.mod to declare fixed versions of its dependencies.
With Go modules, updating a dependency simply involves running `go get`:
```bash
go get package/path # Fetch the latest published version
go get package/path@X.Y.Z # Fetch a specific published version
go get package/path@HEAD # Fetch the latest commit
```
To update ALL dependencies to the latest version run `go get -u`.
Be warned however, that this may undo any selected versions that resolve issues in other non-module repos.
While running `go build` and `go test`, go will add any ambiguous transitive dependencies to `go.mod`
To clean these up run:
```bash
go mod tidy
```
### Running Codebase Checks
The [`scripts/presubmit.sh`](scripts/presubmit.sh) script runs various tools
and tests over the codebase.
#### Install [golangci-lint](https://github.com/golangci/golangci-lint#local-installation).
```bash
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.1
```
#### Run code generation, build, test and linters
```bash
./scripts/presubmit.sh
```
#### Or just run the linters alone
```bash
golangci-lint run
```
## Design
### Design Overview
Trillian is primarily implemented as a
[gRPC service](http://www.grpc.io/docs/guides/concepts.html#service-definition);
this service receives get/set requests over gRPC and retrieves the corresponding
Merkle tree data from a separate storage layer (currently using MySQL), ensuring
that the cryptographic properties of the tree are preserved along the way.
The Trillian service is multi-tenanted – a single Trillian installation can
support multiple Merkle trees in parallel, distinguished by their `TreeId` – and
each tree operates in one of two modes:
- **Log** mode: an append-only collection of items; this has two sub-modes:
- normal Log mode, where the Trillian service assigns sequence numbers to
new tree entries as they arrive
- 'preordered' Log mode, where the unique sequence number for entries in
the Merkle tree is externally specified
In either case, Trillian's key transparency property is that cryptographic
proofs of inclusion/consistency are available for data items added to the
service.
### Personalities
To build a complete transparent application, the Trillian core service needs
to be paired with additional code, known as a *personality*, that provides
functionality that is specific to the particular application.
In particular, the personality is responsible for:
* **Admission Criteria** – ensuring that submissions comply with the
overall purpose of the application.
* **Canonicalization** – ensuring that equivalent versions of the same
data get the same canonical identifier, so they can be de-duplicated by
the Trillian core service.
* **External Interface** – providing an API for external users,
including any practical constraints (ACLs, load-balancing, DoS protection,
etc.)
This is
[described in more detail in a separate document](docs/Personalities.md).
General
[design considerations for transparent Log applications](docs/TransparentLogging.md)
are also discussed separately.
### Log Mode
When running in Log mode, Trillian provides a gRPC API whose operations are
similar to those available for Certificate Transparency logs
(cf. [RFC 6962](https://tools.ietf.org/html/6962)). These include:
- `GetLatestSignedLogRoot` returns information about the current root of the
Merkle tree for the log, including the tree size, hash value, timestamp and
signature.
- `GetLeavesByRange` returns leaf information for particular leaves,
specified by their index in the log.
- `QueueLeaf` requests inclusion of the specified item into the log.
- For a pre-ordered log, `AddSequencedLeaves` requests the inclusion of
specified items into the log at specified places in the tree.
- `GetInclusionProof`, `GetInclusionProofByHash` and `GetConsistencyProof`
return inclusion and consistency proof data.
In Log mode (whether normal or pre-ordered), Trillian includes an additional
Signer component; this component periodically processes pending items and
adds them to the Merkle tree, creating a new signed tree head as a result.

(Note that each of the components in this diagram can be
[distributed](https://github.com/google/certificate-transparency-go/blob/master/trillian/docs/ManualDeployment.md#distribution),
for scalability and resilience.)
Use Cases
---------
### Certificate Transparency Log
The most obvious application for Trillian in Log mode is to provide a
Certificate Transparency (RFC 6962) Log. To do this, the CT Log personality
needs to include all of the certificate-specific processing – in particular,
checking that an item that has been suggested for inclusion is indeed a valid
certificate that chains to an accepted root.
|