{"id":20148284,"url":"https://github.com/chainguard-dev/tlogistry","last_synced_at":"2025-05-06T22:30:45.774Z","repository":{"id":45264544,"uuid":"508309693","full_name":"chainguard-dev/tlogistry","owner":"chainguard-dev","description":"Transparenty Immutable Container Image Tags","archived":true,"fork":false,"pushed_at":"2023-07-05T21:23:07.000Z","size":299,"stargazers_count":20,"open_issues_count":6,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-17T15:58:30.567Z","etag":null,"topics":["container-image","sigstore","transparency-log"],"latest_commit_sha":null,"homepage":"https://tlogistry.dev","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/chainguard-dev.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-06-28T13:25:13.000Z","updated_at":"2024-10-03T06:47:04.000Z","dependencies_parsed_at":"2022-08-27T19:50:22.569Z","dependency_job_id":null,"html_url":"https://github.com/chainguard-dev/tlogistry","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Ftlogistry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Ftlogistry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Ftlogistry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/chainguard-dev%2Ftlogistry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/chainguard-dev","download_url":"https://codeload.github.com/chainguard-dev/tlogistry/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252778858,"owners_count":21802839,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["container-image","sigstore","transparency-log"],"created_at":"2024-11-13T22:36:47.156Z","updated_at":"2025-05-06T22:30:45.444Z","avatar_url":"https://github.com/chainguard-dev.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# `tlogistry.dev`\n\n`tlogistry.dev` is a Docker container image registry implementation that redirects requests to other public image registries.\nWhen it receives a request for an image manifest by mutable tag, it collects the immutable digest associated with that tag, and records it in [Sigstore](https://sigstore.dev)'s transparency log, [Rekor](https://docs.sigstore.dev/rekor/overview).\n\nOn subsequent requests for a manifest by tag, it checks Rekor to see if it's seen that tag before, and fails if the previously recorded digest doesn't match the current one.\n\nThe effect is **transparently verifiable immutable tags for public images**, for any public image registry, without trusting that the registry actually blocks tag updates.\n\n## How To Use It\n\nInstead of:\n\n```\ndocker pull alpine:3.16.0\n```\n\nJust add `tlogistry.dev/`:\n\n```\ndocker pull tlogistry.dev/alpine:3.16.0\n```\n\nOr, in your `Dockerfile`, instead of this:\n\n```\nFROM alpine:3.16.0\n...\n```\n\nJust add `tlogistry.dev/`:\n\n```\nFROM tlogistry.dev/alpine:3.16.0\n...\n```\n\n## How It Works\n\nWhen you pull an image through `tlogistry.dev`, requests for manifests and blobs by immutable content-addressed digest are simply forwared -- `tlogistry.dev` doesn't store any data, it just forwards your request to the real registry.\n\nWhen you pull an image manifest by tag, `tlogistry.dev` proxies the request from the real registry if it can.\nBefore it serves the manifest back to you, it notes the manifest's digest as reported by the real registry.\n\nIt then queries Rekor to see if there have been any previously reported sightings of your image by tag.\nIf so, and if the previous records point to the same digest it's about to serve, it serves the request.\nIf the digest doesn't match, that means someone updated the tag, and the proxied request fails.\nIf there wasn't a previous record of this image by tag, it writes one in Rekor for next time.\n\nThe service runs on [Google Cloud Run](https://cloud.google.com/run), and entries in Rekor contain a keyless signature (using Sigstore's code signing cerificate authority, [Fulcio](https://docs.sigstore.dev/fulcio/overview/)) associated with the service's [service account](https://cloud.google.com/run/docs/configuring/service-accounts).\nThe instance's service account is `tlogistry@kontaindotme.iam.gserviceaccount.com`.\n\nWhen a manifest request consults Rekor, information about the associated entry is included in headers in the response:\n\n```\n--\u003e GET https://tlogistry.dev/v2/registry.example.biz/my/image/manifests/v1.2.3\n\nHTTP/2.0 200 OK\n...\nTlog-Integratedtime: 2022-06-28T13:03:37Z\nTlog-Logindex: 2787015\nTlog-Uuid: 362f8ecba72f432641632fca55dd510f1efcf89105458562f5d5e828262762b5e1ef276ec6d7a00b\n...\n```\n\nIf the request resulted in a new entry being created in Rekor (i.e., if this was the first time the registry has seen the tag), the `Tlog-First-Seen: true` header is also set in the response.\n\n## Deploying\n\n```\ngcloud auth login\ngcloud auth application-default login\nterraform init\nterraform apply -var project=[MY-PROJECT]\n```\n\nThis will build the app with [`ko`](https://github.com/google/ko) and deploy it to your project.\n\nBy default it deploys in `us-east4`, but you can change this with `-var region=[MY-REGION]`.\n\nThe generated Cloud Run URL will be something like https://tlogistry-blahblah-uk.a.run.app, which you can interact with using:\n\n```\ndocker pull tlogistry-blahblah-uk.a.run.app/alpine:3.16.0\n```\n\n## Frequently Asked Questions\n\n### What about `:latest`?\n\nThe `:latest` tag is conventionally updated to point to whatever the \"latest\" version of an artifact is.\n\n`tlogistry.dev` doesn't treat `:latest` differently from any other tag -- the first time it's asked to fetch `alpine:latest`, it will record what digest that tag points to, and prevent future requests that would serve different content.\n\nThis means that the first time you request any image by `:latest` using `tlogistry.dev`, that version will be frozen in time.\nIf `:latest` is updated to point to something else, it will not be able to be pulled through `tlogistry.dev`, as with all tags.\n\nIt is a convenience, but it's also an antipattern if you want reliable, consistent behavior from your container images.\n\n### Aren't I just trusting `tlogistry.dev` not to mutate my tags / sell my data / mine bitcoin?\n\nOh you are clever.\n_Yes you are._\n\nIf you don't want to trust me, you can run an instance of this service yourself.\nEach unique instance of the service runs with a unique GCP service account, and only records written by that service account are accepted when considering entries in Rekor.\n\nIf you don't want to trust immutable tags at all, I recommend pulling images by content-addressed immutable digests.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainguard-dev%2Ftlogistry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchainguard-dev%2Ftlogistry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchainguard-dev%2Ftlogistry/lists"}