Git access
Remote Git operations run on the Mend server. Session workspaces do not receive SSH keys or Git credentials.
Your Git access is per user. Settings → Git access sets the mode for projects you adopt: A
Mend key on your git account (mend-key, the default) or Your machine’s key (bridge).
mend keys mode does the same from the terminal. A project’s Setup page can override the mode
with mend key or bridge, and mend adopt --auth overrides it for one adoption.
Your Mend key
Section titled “Your Mend key”Each Mend user has one ed25519 key, generated and held on the server and never copied into a workspace or the database. Create it with Create my Mend key under Settings → Git access, or from the terminal:
mend keys initmend keys showAdd the printed public key to your Git account’s SSH keys. Every repository your account can reach then works, including from detached sessions, the phone, and the hot pool. For access to one repository only, add the key as that repository’s deploy key instead, and grant it write access only when sessions need to push.
mend adopt git@github.com:acme/api.git --auth mend-keyThe key acts as you and nobody else on the same server: a session signs with its owner’s key.
SSH-agent bridge
Section titled “SSH-agent bridge”Bridge mode keeps the signing key on your machine. The server’s Git operations sign through the SSH agent there, so a hardware key never leaves your desk.
mend adopt git@github.com:acme/api.git --auth bridgeWhen your mode is bridge, every attaching mend command and the dashboard share your machine’s
agent for as long as they run. mend keys share does the same on a machine that is not running one;
Ctrl+C stops it. The server takes one signer per account at a time, and a newer share replaces the
older one.
Git transport bytes travel to the Mend server, while SSH signing requests travel back to the shared
agent. Hardware-key touch happens on the machine holding the key. While no signer is connected, Git
for bridge projects does not wait: the base is not fetched, and pushes fail with a message that says
so. The project’s Setup page shows signer connected · <machine> or no signer connected.
No ambient mode
Section titled “No ambient mode”Until 0.36 a third mode, ambient, used whatever Git and SSH setup existed where the server ran. On
a server from mend server setup or the Kubernetes chart that is a container with no key, agent or
credential, so it reached only public HTTPS remotes, which both modes above reach the same way. It
is gone: upgrading moves each project that used it to its creator’s own mode (mend keys mode), or
to mend-key when they never chose one. A client from before 0.36 that asks for ambient is
refused with:
Mend no longer has an ambient git mode: a packaged server holds no git or ssh credential of its own. Use your Mend key (`--auth mend-key`; `mend keys` prints it to add on your git host) or your own key through `mend keys share` (`--auth bridge`).HTTPS remotes
Section titled “HTTPS remotes”Your Mend key and the bridge sign SSH; neither answers an HTTPS remote, so neither is needed for
one: a bridge project with nobody sharing still adopts and fetches a public HTTPS repository. On a
server from mend server setup (or the Kubernetes chart), Mend’s own Git (adoption, mend refresh,
the base fetch and the push of a landing) runs in a container with no
HTTPS credential, so there an https:// URL clones and fetches a public repository only, and no
push to it succeeds. Adopt the SSH URL instead: git@github.com:acme/api.git rather than
https://github.com/acme/api.git.
A private repository adopted by its HTTPS URL on such a server fails with:
Mend found no HTTPS credential for this remote, so over HTTPS it reaches public repositories only; this one is private, or the URL is wrong. Your Mend key signs ssh remotes only: adopt git@github.com:acme/api.git instead. (observed: fatal: could not read Username for 'https://github.com': terminal prompts disabled)A public one adopts, and its first landing fails at the push with
Mend found no HTTPS credential for this remote: a public repository clones over HTTPS without one, but a push needs one.
followed by the SSH URL to adopt.
Mend names the SSH URL for GitHub, GitLab, Bitbucket and Codeberg on their default HTTPS port, whose SSH path matches the HTTPS one; for other hosts, copy the SSH URL your host shows.
A server you run from source as your own user runs Git with that user’s Git config, so a credential
helper configured there (gh auth setup-git, the macOS keychain) answers HTTPS remotes in either
mode, for clone and push alike, and a url.<base>.insteadOf rewrite applies too. Mend decides who
signs by the URL Git actually dials: an HTTPS URL that a rewrite sends over SSH (insteadOf, or
pushInsteadOf for a landing’s push) signs with your Mend key or your bridge like any SSH remote.
Mend’s own SSH never answers with the server process’s agent, default keys or SSH config: where Mend
resolved no signer, SSH refuses.
When Mend signs (your Mend key, your bridge, or a session’s Git through the workspace transport), it
ignores the server user’s ~/.ssh/config, so an IdentityFile or IdentityAgent there cannot
stand beside or replace Mend’s choice. A server run from source that reached a Git host through a
Host alias or a ProxyJump in that file must use the host’s real name in the project’s URL, and a
host reachable only through a jump host is not reachable from Mend’s Git.
Git inside a workspace
Section titled “Git inside a workspace”Mend points the workspace’s system Git config at a transport shim (core.sshCommand). Plain
commands still work:
git fetchgit pushThe shim carries the SSH transport over the session socket. The Mend server resolves the project’s
current authentication mode, signs as the session’s owner, and opens the remote connection. In a
per-person workspace it signs as the person whose process runs
git, with their Mend key or their own bridge, so a joiner’s push is the joiner’s. Git over HTTPS
to GitHub there uses Mend’s credential helper, which answers with the GitHub login in that person’s
own home. No SSH credential enters the container. The socket carries Git’s own remote commands only
(git-upload-pack, git-receive-pack, git-upload-archive).
The shim signs only for the project’s own origin host. A fetch or push to another host is refused
with
this session's Git access is bound to <origin host>; pushes and fetches to <host> run without Mend's signer.
An operator on a machine they alone use can set MEND_GIT_TRANSPORT_BIND_ORIGIN=false to let the
shim sign for any host, for mirrors and forks.
In a captured workspace (the default store) the repository is built from captures and has no remote
of its own. Mend names the project’s origin for the workspace, with any login or token in an HTTPS
URL removed before it gets there; an SSH login name stays.
Mend records the remote operation and its outcome. Changing the project’s auth mode applies to the next Git operation without rebuilding the workspace.
Git author
Section titled “Git author”Commits the agent makes in your workspaces name your Git author. Until you set one, it is the name and email you registered with. Change it under Settings → Git author, or from the terminal:
mend git-author "Anna Example" anna@example.commend git-author --clearmend git-author with no arguments prints the current author and where it comes from. --clear
returns to your account’s name and email.
Mend writes the author into each workspace as system Git config before the agent starts. A user
section in your dotfiles .gitconfig or in a repository’s own config still
decides. Sessions launched after a change commit as the new author.
In a per-person workspace each person commits as themselves: Mend writes your author into your own
home (~/.mend/git-author, included at the top of ~/.config/git/config) when your user is given
its identity, so a changed author applies from your next start there.
Where Mend’s own Git may reach
Section titled “Where Mend’s own Git may reach”Adoption, reference repositories, and dotfiles clone from a URL someone typed, with the server’s
network position. MEND_SOURCE_POLICY decides which addresses those clones may reach:
operator(the default) fits one team’s own machine: private networks are allowed, the cloud metadata service never is, and loopback or link-local addresses only for the operator;tenantrefuses private, reserved, and local addresses, and unauthenticatedgit://, unlessMEND_SOURCE_ALLOWED_HOSTS(a comma-separated list) names the host. Loopback and the metadata service can never be allowed.
Read Server environment for every server variable.
No credentials in repository URLs
Section titled “No credentials in repository URLs”Mend refuses a repository URL that carries a login or token, such as
https://oauth2:TOKEN@gitlab.com/acme/api.git or https://ghp_…@github.com/acme/api.git, wherever
one is typed: adoption, reference repositories and dotfiles, in the CLI, the web, the phone, VS Code
and the API. Mend shows a project’s URL to everyone who can see the project, which on a shared
project is the whole organization, so a token in it would be theirs to read. mend adopt from a
checkout whose origin carries one is refused the same way.
This URL carries a login or token before the "@". Mend shows a repository URL to everyone who cansee the repository, so it never stores one. Use the SSH URL (git@host:owner/repo.git) with your Mendkey (`mend keys` shows it), or your own key through the agent bridge (`--auth bridge`).An SSH login name is not a credential and stays: git@github.com:acme/api.git and
ssh://git@example.com/acme/api.git are accepted as typed. Use the SSH URL with your Mend key or
the bridge; on a server you run from source as your own user, that user’s Git credential helper
answers an HTTPS URL without a token in it (see HTTPS remotes).
Mend also removes a credential from any repository URL it returns or logs, and from the Git errors it reports. For projects adopted before 0.36, see Known issues.
GitHub connected accounts are separate
Section titled “GitHub connected accounts are separate”mend connect github supplies a GitHub token to gh and compatible API clients inside workspaces.
It does not choose how the server clones, fetches, or pushes the repository.
Landing a change uses both: the push goes over the project’s Git access, and the pull request is opened or updated as your connected GitHub account.
Use provider accounts for GitHub API access. Use a Git auth mode for repository transport.
Common failures
Section titled “Common failures”Permission denied means the selected identity cannot access the remote. Add your Mend public key to your Git account, or verify that the shared agent holds an authorized key.
Mend found no HTTPS credential for this remote means the URL is https:// and the server’s Git
has no credential for it: the repository is private (or the URL is wrong), or the operation was a
push. Adopt its SSH URL; see HTTPS remotes.
Host key verification failed means the remote’s host key changed since the Mend server first saw
it: every mode accepts a first-contact key and refuses a changed one. Verify the new key out of
band, then fix the known_hosts entry where the server’s Git runs. Do not disable host-key checking
in a workspace.
No signer connected means bridge mode has no machine sharing its agent. Run any attaching mend
command, or mend keys share, on the machine holding the key.
Git access is bound to another host means the workspace tried to reach a remote other than the project’s origin. See Git inside a workspace.