chartered ✈️
Chartered is an alternative registry implementation that goes a little bit futher than your bog-standard registry, providing AAA (authentication, authorisation & accounting) guarentees for each of your crates.
Sections
To get started with Chartered, running the servers & uploading your first crate.
The guide will give you the run down on all things chartered.
Appendices:
Other documentation:
Getting Started
To get started with Chartered, run the server and upload your first crate.
Server Installation
Chartered's server comes in 3 parts:
- chartered-git: hosts the git server which clients grab the crate index from, along with their credentials to grab the crates from the next service,
- chartered-web: hosts the API portion of chartered, which serves the crates themselves (or a redirect to them, depending on which storage backend you're using) and hosts the "web API" which is consumed by our final service,
- chartered-frontend: a React-based crates.io-like web UI for viewing crates, managing organisations and viewing AAA data.
Each of these services are hosted separately from one another, and could technically be swapped out for other implementations - the only shared layer between the three of them is database storage for crate lookups and authentication credential vending. All of the services have the ability to be clustered with no extra configuration.
Backend Services
chartered-git
and chartered-web
's setups are similar, first they need a database set up -
either SQLite or PostgreSQL, PostgreSQL is recommended anywhere outside of development/local
use for obvious reasons.
Both the aformentioned services have sane defaults for development and can be ran simply by
running the binary, the services will bind to 127.0.0.1:8899
and 127.0.0.1:8080
respectively
and store crate files in /tmp/chartered
, configuration away from these defaults is simple.
Using the recommended setup, S3 & PostgreSQL:
chartered-web
config
bind_address = "127.0.0.1:8080"
database_uri = "postgres://user:password@localhost/chartered"
storage_uri = "s3://s3-eu-west-1.amazonaws.com/my-cool-crate-store/"
frontend_base_uri = "http://localhost:5173/"
[auth.password]
enabled = true
# openid connect provider
[auth.gitlab]
enabled = true
discovery_uri = "https://gitlab.com/"
client_id = "[client-id]"
client_secret = "[client-secret]"
chartered-git
config
bind_address = "127.0.0.1:2233"
database_uri = "postgres://user:password@localhost/chartered" # can also be `sqlite://`
web_base_uri = "http://localhost:8888/"
[committer]
name = "Chartered"
email = "noreply@chart.rs"
message = "Updated crates!"
These configuration files can be passed into each binary using the -c
CLI argument.
Alternative crate stores will be considered, please consider contributing or create an issue on GitHub. MySQL support, however, is a no-go.
chartered-web
& chartered-git
can be built from source easily or ran using the
Dockerfile:
$ docker build https://github.com/w4/chartered.git#main \
--target chartered-web \
-t chartered-web:master
$ docker build https://github.com/w4/chartered.git#main \
--target chartered-git \
-t chartered-git:master
$ docker -v $PWD/web-config.toml:/config.toml run -d chartered-web --config /config.toml
$ docker -v $PWD/git-config.toml:/config.toml run -d chartered-git --config /config.toml
Frontend
The frontend only needs to be configured to point to the chartered-web
service. This can be
done by changing the bundled config.json
. This can then be hosted in S3/minio/your preferred
static hosting platform, a Dockerfile can also be built which uses static-web-server
to run on your own server without another way of hosting static content:
# buildkit doesn't yet support subdirectories for git repositories
$ DOCKER_BUILDKIT=0 docker build \
https://github.com/w4/chartered.git#main:chartered-frontend \
--build-arg BASE_URL=https://api.my.instance.chart.rs \
-t chartered-frontend:master
$ docker run -d -p 8080:80 chartered-frontend:master
$ curl http://127.0.0.1:8080
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8">...
Where BASE_URL
points to the chartered-web
instance.
User Guide
Using chartered as a user is actually pretty simple, it's very much like your standard Cargo registry except with two extra concepts: organisations and permissions.
Organisations are very much like the organisations you'll likely have used on your preferred SCM host, a group of users that have group-level permissions, in Chartered case the permissions these users may have are:
Permissions
VISIBLE
- Essentially the base-level permission meaning the user belongs to the group, if the user doesn't have this permission they're not in the group, this permission at the crate-level means the user can download the crate and see it in the WebUI.
PUBLISH_VERSION
- Gives the ability to publish a new version for crates belonging to the group.
YANK_VERSION
- Gives the ability to yank (and unyank) published versions for crates belonging to the group.
MANAGE_USERS
- Gives the ability to add (and remove) users from the group, and crates belonging to the organisation.
CREATE_CRATE
- Gives the ability to create a new crate under the organisation.
All these permissions, with the exception of CREATE_CRATE
, can also be used at the
crate-level for giving extra permissions to org members for a particular crate - or
even users outside of the org. Bare in mind, however, these permissions are additive -
it is not possible for permissions to be subtracted from a user at the crate-level
if they have been granted them by the organisation.
Publishing your first crate
With all this in mind, it's about time you started publishing your first crate!
Chartered has excellent integration with Cargo's alternative registry implementation and is used very much like a standard alternative registry. The only prerequisites for publishing your crate are:
- Have an SSH key added to your Chartered account, which you can do via the WebUI
- Belong to an organisation you have the
PUBLISH_VERSION
permission for, anyone can create a new organisation if you don't already belong to one.
And once you're ready, you can add the organisation's registry to your .cargo/config.toml
like so:
[registries]
my-organisation = { index = "ssh://ssh.chart.rs/my-organisation" }
(You should create this file if it doesn't already exist)
You can now publish the crate using cargo as you normally would, except with the registry specified:
$ cargo publish --registry my-organisation --token ""
Note: the token is purposefully empty, as the token will be vended by the index based on your SSH key.
Pulling in dependencies
Again, not too dissimilar from using crates.io, you can declare your dependencies
as normal with the exception that you need to specify the organisation the crate should
be pulled from provided you've declared the organisation in .cargo/config.toml
as shown
in the previous section of this guide.
[dependencies]
my-other-crate = { version = "0.1", registry = "my-organisation" }
Your other Cargo dependencies from crates.io can be declared as normal alongside organisation dependencies.
Chartered Guide
Configuration Reference
An exhaustive list of all configuration values in chartered.
Configuration files are written in the TOML format, with simple key-value pairs inside of sections (tables). The following is a quick overview of all settings, with detailed descriptions found below
chartered-git
Configuration format
bind_address = "127.0.0.1:2233"
database_uri = "postgres://user:password@localhost/chartered" # can also be `sqlite://`
web_base_uri = "http://localhost:8888/"
[committer]
name = "Chartered"
email = "noreply@chart.rs"
message = "Updated crates!"
Configuration keys
bind_address
- Type: string
The IP address and port the web server should be bound to.
database_uri
- Type: string
A connection string for the backing database, either postgres
or sqlite
, either in the
format of postgres://user:password@localhost/chartered
(a postgres connection URI),
sqlite:///path/to/chartered.db
or sqlite://:memory:
.
web_base_uri
- Type: string
The path at which the Chartered API (chartered-web
) is running. This should always be HTTPS when
running in production.
committer
The committer
table defines the author of the commit that's sent to the
user.
name
- Type: string
- Default:
chartered
The name of the committer for any commits being created by chartered-git
.
email
- Type: string
- Default:
noreply@chart.rs
The email address to list for the author of the commit pushed to the user
message
- Type: string
- Default:
Update crates
The commit message to use for any commits sent out.
chartered-web
Configuration format
bind_address = "127.0.0.1:8080"
database_uri = "postgres://user:password@localhost/chartered" # can also be `sqlite://`
storage_uri = "s3://s3-eu-west-1.amazonaws.com/my-cool-crate-store/" # or file:///var/lib/chartered
frontend_base_uri = "http://localhost:5173/"
trusted_ip_header = "x-forwarded-for"
[auth.password]
enabled = true # enables password auth
[auth.<provider>] # openid connect provider
enabled = true
discovery_uri = "https://gitlab.com/"
client_id = "[client-id]"
client_secret = "[client-secret]"
Configuration keys
bind_address
- Type: string
The IP address and port the web server should be bound to.
database_uri
- Type: string
A connection string for the backing database, either postgres
or sqlite
, either in the
format of postgres://user:password@localhost/chartered
(a postgres connection URI),
sqlite:///path/to/chartered.db
or sqlite://:memory:
.
storage_uri
- Type: string
A URI in which crates should be stored, this can either be an s3://
connection URI, or a local file path using
file://
.
frontend_base_uri
- Type:
string
The base URL at which the frontend is being hosted.
trusted_ip_header
- Type:
string
- Default: null
Allows a header to override the socket address as the end user's IP address
[auth.password]
The [auth.password]
table controls the username/password-based authentication method.
enable
- Type: bool
- Default: false
Enables username/password-based authentication and registration.
[auth.<provider>]
[auth.<provider>]
tables represent an OpenID Connect provider that can be used to
login and register to the chartered instance. <provider>
should not be changed once
set as the value is stored in the database along with users.
enabled
- Type: bool
Enables the authentication provider, if this is disabled users will not be able to login nor register using the provider.
discovery_uri
- Type: bool
The OIDC Discovery URI that can be used to grab configuration for the provider, not including
/.well-known/openid-configuration
.
client_id
- Type: string
The Client ID given by the provider to identify the service.
client_secret
- Type: string
The client secret given by the provider to authenticate the service.