---
Add some documentation and stuff
README.md | 2 +-docs/sourcehut_authentication.md | 93 ++++++++++++++++++++++++++++++++
2 files changed, 94 insertions(+), 1 deletion(-)
create mode 100644 docs/sourcehut_authentication.md
diff --git a/README.md b/README.md
index 1dc442a..b7da361 100644
--- a/README.md+++ b/README.md
@@ -31,7 +31,7 @@ to perform authorization, and this separate service is implemented by this appli
srht-registry supports the following authentication methods:
* Username and password (regular `docker login`)
* Anonymous authentication (`docker pull` without previous login)
-* Sourcehut CI/CD (builds.sr.ht) authentication by using the `oauth` grant in your build manifest+* [Sourcehut CI/CD (builds.sr.ht) authentication](docs/sourcehut_authentication.md) by using the `oauth` grant in your build manifestThe last method is the main benefit of using this implementation.
In short, it allows you to authorize a build running in builds.sr.ht to pull or push docker images, _without_ storing any long-lived secrets.
diff --git a/docs/sourcehut_authentication.md b/docs/sourcehut_authentication.md
new file mode 100644
index 0000000..f916d5d
--- /dev/null+++ b/docs/sourcehut_authentication.md
@@ -0,0 +1,93 @@
+# Sourcehut authentication++This is the main benefit of using `srht-registry`.++In short, it allows you to authorize a build running in builds.sr.ht to pull or push docker images, _without_ storing any long-lived secrets.+Instead, authentication to the container registry is done using the Sourcehut OAuth2 token.+This authorization server will then validate the token by contacting `meta.sr.ht`, and extract grants from the token, which is then used for authorization purposes.++## Flow++The flow looks like this, with these entities:+* Docker: The docker client of the user, on their local computer.+* Registry: The registry itself, i.e. an instance of [distribution/distribution](https://github.com/distribution/distribution/).+* srht-registry: An instance of this project.+* Sourcehut: A Sourcehut instance, e.g. sr.ht or a self-hosted instance.++```+Docker Registry srht-registry Sourcehut++| attempt pull from registry +|--------------------------->|+ |+ refer to authz server |+|<---------------------------|+|+| authenticate using sourcehut token+|---------------------------------------------->| validate token+ |-------------------->|+ |+ success/failure |+ |<--------------------|+ |+ perform authorization and return |+ token with authorized grants |+|<----------------------------------------------|+|+|+| pull w. token+|--------------------------->|+ |+ return data |+|<---------------------------|+```++The steps are these:++1. The docker client attempts to pull something, e.g. using `docker pull registry.example.com/some/image:latest`. It contacts `registry.example.com` without any credentials.+2. The registry will return a response tell the client to authenticate by contacting a third-party service, in this case srht-registry. For example `auth.registry.examplec.com`.+3. The docker client sends credentials to srht-registry, in this case a placeholder username and as password a Sourcehut token with the correct grants.+4. srht-registry will validate the token, by performing the following steps:+ 1. Send a test request to the Sourcehut instance, since this is the only way to check that the signature of the token is correct.+ 2. If the token was signed correctly, srht-registry proceeds with parsing the token, extracting the grant string and expiry date.+ 3. Check that the grant contains `registry.example.com/REGISTRY:RW` (or is empty), this ensures that token is not just any token, but meant for container images.+ 4. Extracts the username and uses it to check the ACL for authorization.+5. Return a signed JWT to the Docker client.+6. The docker client attaches the signed JWT to the request to the registry. The registry checks that it is signed with the correct key (the public key or srht-registry is shared with the registry).+7. Registry allows push or pull.++## Sourcehut tokens in builds.sr.ht++The main purpose of srht-registry is to make it easy to push from a builds.sr.ht pipeline.+This is easily done by using a build manifest such as this.+Note specifically that the `oauth:` line requests a short-lived token with the correct grant.++```yaml+image: alpine/edge+packages:+- docker+- docker-cli-buildx+sources:+- https://git.sr.ht/~zozs/test+oauth: "registry.example.com/REGISTRY:RW" # important: will generate a sourcehut oauth2 token with the correct grant+tasks:+- setup: |+ sudo service docker start+ sudo addgroup $USER docker+- buildpush: |+ cd test+ set +x+ docker login registry.zozs.se -u sourcehut -p "$OAUTH2_TOKEN"+ set -x+ docker buildx build --push --tag registry.zozs.se:zozs/test:latest .+```++## Grant strings++Currently, srht-registry accepts either a grant string that contains `registry.example.com/REGISTRY:RW` (with the correct domain), or a completely empty grant string (which corresponds to all access in other parts of sourcehut).++Setting the grant string to `registry.example.com/REGISTRY:RW` is preferred, since this ensures that the token *can only be used for srht-registry*.+In particular, it means that you don't have to trust srht-registry, since the token *cannot* be used to read or modify any Sourcehut data.++Support for an empty grant string is included because it allows Personal Access Tokens to be used also for pushing or pulling images.+These tokens have a closed set of allowed grant strings, so they cannot include `registry.example.com/REGISTRY:RW`.
--
2.46.0