Skip to content

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.

  1. 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
  1. 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.