# Courier Let your AI agent use your credentials without handing it your secrets. Fetch code, call APIs and download private packages while keeping SSH private keys and access tokens outside your agent's reach. You approve their use; the agent works through ordinary Git commands or Courier's command-line client. Courier currently supports: - Git push/pull of SSH and HTTPS remotes - API access to e.g. GitLab, Jira, etc authenticated by personal access tokens - Download from GitLab registries authenticated by personal access tokens Docker push/pull is coming soon! ## Basic idea Courier creates a new user `courier-broker` that holds all credentials. Your normal user cannot read or manipulate those credentials. This means that your agent - if running as your normal user - cannot read them either. Through a simple command line interface, you initiate the creation of keys or register existing keys with courier. These keys are then stored under the courier broker account. Any operation performed by your agent communicates with the broker to authorize requests, or update requests with authentication tokens. This happens in a way such that secrets never enter the agent context. Courier also keeps a record of which endpoints/API actions your agent is allowed to use. So apart from keeping the secrets safe, courier also puts restrictions on what they can be used for. Configuration of secrets and restrictions is done by you supplying your password at every action. This ensures that your agent cannot change secrets and restrictions on your behalf - assuming you don't tell your agent your password. ## Related work There are several existing solutions that are excellent alternatives to courier. Some are hosted by major tech providers, some run locally in the same manner as courier. Pick the one that suits your purpose best, but just pick one. Keep your secrets out of reach of your model providers. ## Using the downloads You can install and configure Courier without cloning its source repository. Download the combined `courier_VERSION_all.deb` package, `courier-skill.tar.gz` and this README. Install the `.deb` with `sudo apt install ./courier_VERSION_all.deb`, substituting the version in your downloaded filename. Extract the AI assistant skill: ```sh tar -xzf ./courier-skill.tar.gz ``` Ask your assistant to read `courier/SKILL.md`, or install the entire extracted `courier/` folder in its supported skill location. Keep its `references/` folder with it. Tell the assistant which repositories, APIs or registries you want to use; enter passwords and secrets yourself through Courier's terminal prompts. After installation, the full user guides are available locally: - `/usr/share/doc/courier/installation.md` - `/usr/share/doc/courier/client-setup.md` - `/usr/share/doc/courier/git-https.md` - `/usr/share/doc/courier/ssh-design.md` Relative `doc/` and `skills/` links in this README refer to the source checkout; for download-only use, read the installed guides or extracted skill instead. Adapt the example repositories and accounts below to your own workflow. ## Example: Git over SSH This guide sets up a new Courier installation and clones: ```text git@gitlab.icelab.dk:icelab/courier.git ``` You need a Debian/Ubuntu machine with systemd, administrator access through `sudo`, and a GitLab account with access to the repository. Perform the setup yourself, keeping passwords and private credentials out of your agent’s prompts. ### 1. Install Courier Obtain the Courier Debian package from your administrator or project maintainer. From the directory containing it, run: ```bash sudo apt install ./courier_0.1.0-4_all.deb ``` Adjust the filename if you received a newer version. Add your normal account to Courier’s SSH groups: ```bash sudo usermod --append --groups courier-ssh-clients,courier-ssh-admins "$USER" ``` These groups allow you to use the protected keys and administer them through password-required sudo commands. **Log out completely and log back in** so the group memberships take effect. ### 2. Create a protected SSH key ```bash sudo courier-ssh-admin generate gitlab-icelab ``` `gitlab-icelab` is your local name for this credential. Choose a passphrase, or leave it empty. After loading, keys without passphrases restore automatically after restart; passphrase-protected keys require manual loading again. Courier stores the private key under its protected account and prints the **public key**. To display the public key again: ```bash sudo courier-ssh-admin public-key gitlab-icelab ``` ### 3. Register the public key in GitLab Sign in to `https://gitlab.icelab.dk`. Open your avatar menu, select **Edit profile**, then **Access → SSH keys → Add new key**. Paste the complete public-key line, give it a descriptive title, and choose **Authentication** as the usage type. Save the key. [GitLab instructions](https://docs.gitlab.com/user/ssh/#add-an-ssh-key-to-your-gitlab-account) Copy only the public key—the line beginning with `ssh-ed25519`. The private key stays inside Courier. ### 4. Verify and trust the GitLab server Open this page in your browser: ```text https://gitlab.icelab.dk/help/instance_configuration#ssh-host-keys-fingerprints ``` Find the server’s **ED25519 SHA256 fingerprint**. This identifies the server and is different from your own key’s fingerprint. Use that verified value: ```bash sudo courier-ssh-admin trust-host gitlab.icelab.dk \ --fingerprint 'SHA256:REPLACE_WITH_THE_VERIFIED_FINGERPRINT' ``` Courier retrieves the server key and saves it only if the fingerprint matches. ### 5. Allow your account to use the credential Find your Linux username: ```bash whoami ``` Create a file named `courier-ssh-policy.json` containing the following. Replace `YOUR_LINUX_USERNAME` with that username: ```json { "version": 1, "identities": { "gitlab-icelab": { "allowed_local_users": ["YOUR_LINUX_USERNAME"], "allowed_destinations": [ { "host": "gitlab.icelab.dk", "user": "git" } ] } } } ``` Install it: ```bash sudo courier-ssh-admin policy install ./courier-ssh-policy.json ``` Review the displayed account, identity and destination before confirming. This example is for a fresh installation. Installing a policy replaces the previous policy, so later additions must preserve any existing permissions you want to keep. ### 6. Load the credential ```bash sudo courier-ssh-admin load gitlab-icelab sudo courier-ssh-admin check ``` Enter the key’s passphrase if prompted. You should see confirmation that the identity was added and the checks passed. ### 7. Clone the repository through Courier From the directory where you want the checkout: ```bash courier-cli clone-ssh git@gitlab.icelab.dk:icelab/courier.git ``` Run this **without sudo**. On the first connection, SSH may also ask to remember the server in your normal account’s known-hosts file. Verify the displayed fingerprint against the GitLab page before answering `yes`. The command creates a `courier` directory and saves the Courier connection settings. **No separate attachment is needed.** To choose another directory name: ```bash courier-cli clone-ssh git@gitlab.icelab.dk:icelab/courier.git courier-checkout ``` ### 8. Start working normally ```bash cd courier git status git pull --ff-only ``` Before your first commit, set your Git identity for this repository: ```bash git config user.name "Your Name" git config user.email "you@example.com" ``` For example, create a branch, make your edits, and publish it: ```bash git switch -c my-first-change ``` After editing `README.md`: ```bash git add README.md git commit -m "Update documentation" git push -u origin my-first-change ``` Git uses Courier automatically. GitLab still controls which repositories and branches your account may read or update. For subsequent sessions, loaded keys without passphrases restore automatically by default. If your key has a passphrase, load it again after restarting: ```bash sudo courier-ssh-admin load gitlab-icelab ``` ## Example: Git over HTTPS Once you have [configured an HTTPS token, policy and the webproxy](doc/git-https.md#initial-setup), clone as your normal user: ```bash courier-cli clone-https https://gitlab.cept.org/SEAM/seamcat.git \ --credential GITLAB_CEPT_TOKEN cd seamcat git pull --ff-only ``` `GITLAB_CEPT_TOKEN` is the token's name in Courier, never the token value. The initial clone and later Git commands use Courier automatically, while the original HTTPS URL stays stored as `origin`. No separate attachment is needed. Push requires explicit policy permission and a token with write access. See [HTTPS cloning](doc/client-setup.md#clone-https) for destination and proxy-port options. ## Other transport options Courier also supports API access to e.g. Gitlab or Jira or download of Gitlab registry artifacts. These types of requests are routed through a local web proxy also part of courier. This proxy hands over the request to courier, and then courier inserts your personal access tokens, performs the request and routes the response back to the client. All manipulation of credentials happen in the courier-broker user space and is not visible to your client. For workflow-specific setup, ask your AI to use the Courier skill described above, with questions such as: 1) How do I configure courier and my agent to allow my agent to read all pending merge request on my gitlab project? 2) How do I configure courier and my agent to allow my agent to read all Jira tickets assigned to me? 3) How do I configure gradle to download dependencies from my company registry without exposing my gitlab token to my agent? Or come up with your own question about how to do a specific workflow you normally do, but this time without exposing your secrets to your agent. Chances are that courier supports it, and if it doesn't, file a request with the courier project to get it implemented. ## AI assistant skill The [Courier skill](skills/courier/SKILL.md) helps an AI assistant install, configure, use and troubleshoot Courier for Git, API and private-registry workflows. Give your assistant that entrypoint, or copy the entire `skills/courier/` folder into its supported skill location. Keep the bundled references with it; the skill can be distributed separately from the source repository. Passwords, tokens and private-key passphrases are entered by the human through Courier's administrative terminal prompts.