A tool by Icelab

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.

Download Courier

For Debian/Ubuntu with systemd. Administrator access through sudo is required.

Download README (.md)

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.

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:

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:

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:

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:

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

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:

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

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:

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:

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:

whoami

Create a file named courier-ssh-policy.json containing the following. Replace YOUR_LINUX_USERNAME with that username:

{
  "version": 1,
  "identities": {
    "gitlab-icelab": {
      "allowed_local_users": ["YOUR_LINUX_USERNAME"],
      "allowed_destinations": [
        {
          "host": "gitlab.icelab.dk",
          "user": "git"
        }
      ]
    }
  }
}

Install it:

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

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:

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:

courier-cli clone-ssh git@gitlab.icelab.dk:icelab/courier.git courier-checkout

8. Start working normally

cd courier
git status
git pull --ff-only

Before your first commit, set your Git identity for this repository:

git config user.name "Your Name"
git config user.email "you@example.com"

For example, create a branch, make your edits, and publish it:

git switch -c my-first-change

After editing README.md:

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:

sudo courier-ssh-admin load gitlab-icelab

Example: Git over HTTPS

Once you have configured an HTTPS token, policy and the webproxy, clone as your normal user:

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