Publishing to a custom domain

By default, modules in the Central Registry live under the github.com namespace – for example github.com/cueckoo/frostyconfig. The Publishing modules tutorial walks through that flow.

You can also publish modules under a domain that you control, such as acme.example/frostyconfig. These are called custom domains (sometimes vanity domains). This guide explains how they work and how to set one up.

How it works

When the Central Registry handles an operation on a module whose path begins with github.com, it uses GitHub directly to decide who may publish and read: you can publish github.com/acme/frostyconfig only if you have push access to the github.com/acme/frostyconfig repository.

For any other host, the registry instead fetches a small JSON file from the domain itself:

https://<host>/.well-known/cue-central-registry.json

This file nominates a GitHub repository to act as a proxy for authorization over the whole domain:

  • Anyone who can push to that repository may publish modules under the domain.
  • Anyone who can pull from that repository may fetch modules under the domain.

So, to publish acme.example/frostyconfig, you serve a cue-central-registry.json file at acme.example that points at a GitHub repository you control. Proving that you can serve a file at https://acme.example/.well-known/... proves that you control the domain, following the .well-known convention (RFC 8615).

The Central Registry is in beta testing

Please give us your feedback about the service in the #modules channels on Slack and Discord.

The .well-known file

The file must be served over HTTPS, at exactly the path /.well-known/cue-central-registry.json, on the same host as the module path. A minimal file looks like this:

.well-known/cue-central-registry.json
{
	"auth": {
		"type": "github",
		"repo": "acme/cue-modules"
	}
}

Fields

The fields are described by the following schema, in which ! marks a required field and ? an optional one:

Schema
// auth configures how the registry decides who may publish and
// fetch modules under the domain.
auth!: {
	// type selects the authorization provider. Currently only
	// "github" is supported.
	type!: "github"

	// repo is the GitHub repository, in "owner/name" form, used as
	// the authorization proxy for the domain.
	repo!: string
}

// cacheDuration is how long the registry may cache this file before
// re-fetching, as a duration string such as "24h". It is a hint; see
// the Caching section below.
cacheDuration?: string

The file must be no larger than 10 kB.

Setting up a custom domain

  1. Choose your module path. Pick the host you control and the path for your module, for example acme.example/frostyconfig.

  2. Choose the authorization repository. Decide which GitHub repository will control access to the domain, for example github.com/acme/cue-modules.

  3. Serve the .well-known file. Make https://acme.example/.well-known/cue-central-registry.json return the JSON shown above, naming your authorization repository.

  4. Log in to the Central Registry, if you haven’t already:

    TERMINAL
    $ cue login

    See Login to the Central Registry for details.

  5. Initialize the module with your custom path. As when publishing under github.com, --source=git tells cue to publish exactly the files that git tracks:

    TERMINAL
    $ cue mod init --source=git acme.example/frostyconfig@v0
  6. Publish, after committing your work so the module is in a clean state:

    TERMINAL
    $ cue mod publish v0.0.1

    The registry fetches your .well-known file, checks that you have push access to the authorization repository, and publishes the module.

Other modules can now depend on acme.example/frostyconfig exactly as they would depend on a github.com module.

Public and private modules

Whether a module is public or private is determined by the authorization repository at the time the module is published:

  • If the authorization repository is public when the module is published, the module is public. Public modules can be read by anyone, and the registry does not re-check the .well-known file for read requests – this keeps reads fast. As with all published modules, a public module cannot later be made private.
  • If the authorization repository is private, reads are checked against the .well-known file and require read access to the repository.

Caching

The registry caches the contents of the .well-known file so it does not have to fetch it on every request. By default a file is cached for 24 hours, and the cacheDuration hint cannot reduce the cache below 1 hour. As a result, changes to the file – including changes to the authorization repository it names – may take up to the cache duration to take effect.

Limitations

  • Only github authorization is currently supported.
  • A single .well-known file authorizes the whole host; per-subpath rules and subdomain wildcards are not supported for now.
Install CUE