Rust implementation of OCI Distribution Spec with granular access control
Rust 99.5%
Dockerfile 0.5%
63 1 0

Clone this repository

https://tangled.org/pierrelf.com/grain https://tangled.org/did:plc:meotu43t6usg4qdwzenk4s2t/grain
git@tangled.org:pierrelf.com/grain git@tangled.org:did:plc:meotu43t6usg4qdwzenk4s2t/grain

For self-hosted knots, clone URLs may differ based on your setup.

Download tar.gz
README.md

pierrelefevre/grain#

Rust implementation of OCI Distribution Spec with granular access control

Installation#

Using Docker#

docker pull ghcr.io/pierrelefevre/grain:latest
docker run -p 8888:8888 -v $(pwd)/data:/data ghcr.io/pierrelefevre/grain:latest

See docs/deployment.md for complete deployment guide.

Using Docker Compose#

# Download docker-compose.yml from repository
docker-compose up -d

From Source#

git clone https://github.com/pierrelefevre/grain.git
cd grain
cargo build --release
./target/release/grain --host 0.0.0.0:8888 --users-file ./data/users.json

Quick Start#

  1. Create a data/users.json file:
{
  "users": [
    {
      "username": "admin",
      "password": "admin",
      "permissions": [
        {"repository": "*", "tag": "*", "actions": ["pull", "push", "delete"]}
      ]
    }
  ]
}
  1. Run the registry:
docker run -p 8888:8888 -v $(pwd)/data:/data ghcr.io/pierrelefevre/grain:latest
  1. Use with Docker:
docker login localhost:8888
docker tag alpine:latest localhost:8888/myorg/alpine:latest
docker push localhost:8888/myorg/alpine:latest

Goals#

  • Implement the OCI Distribution Spec in Rust
  • Use local filesystem for storage
  • Use basic auth scheme
  • Provide granular access control per tag
  • Administration API to manage permissions
  • Publish the registry as a container image on GHCR
  • CLI tool for administration tasks

Admin API#

  • Add/remove users
  • Set pull permission for user on tag
  • Interactive API documentation available at /swagger-ui/ when server is running
  • OpenAPI schema available at /api-docs/openapi.json

Admin API Endpoints#

Authentication: All admin endpoints require HTTP Basic Auth with admin privileges (user must have wildcard delete permission on */*).

GET /admin/users - List all users with their permissions

POST /admin/users - Create a new user

{
  "username": "string",
  "password": "string",
  "permissions": [
    {
      "repository": "string",
      "tag": "string",
      "actions": ["pull", "push", "delete"]
    }
  ]
}

DELETE /admin/users/{username} - Delete a user (cannot delete yourself)

POST /admin/users/{username}/permissions - Add permission to a user

{
  "repository": "string",
  "tag": "string",
  "actions": ["pull", "push", "delete"]
}

CLI Administration Tool#

A separate grainctl binary is provided for easy administration via command line.

Installation#

cargo build --release
# Binary will be at target/release/grainctl

Configuration#

Set environment variables to avoid repeating credentials:

export GRAIN_URL=http://localhost:8888
export GRAIN_ADMIN_USER=admin
export GRAIN_ADMIN_PASSWORD=admin

Or use command-line flags for each command.

Commands#

List all users:

grainctl user list
# or with explicit credentials:
grainctl user list --url http://localhost:8888 --username admin --password admin

Create a new user:

grainctl user create alice --pass alicepass

Delete a user:

grainctl user delete alice

Add permission to a user:

grainctl user add-permission alice \
  --repository "myorg/myapp" \
  --tag "dev" \
  --actions "pull,push"

Use wildcards for broader permissions:

grainctl user add-permission alice \
  --repository "myorg/*" \
  --tag "*" \
  --actions "pull"

Spec#

OCI Distribution Spec v1.1.1