
Short recommendation: for a shared git workflow across several developer accounts, start a Figment M-series Mac configuration (from $95/month; exact chip, RAM, disk and SSH access confirmed in the written quote) at /mac-hosting/start. The $29 virtual Intel macOS plan is reached through a browser desktop console rather than inbound SSH, so agent forwarding targets a physical M-series host instead.
A rented Mac shared by several developers needs clean per-user git identity so every commit is correctly attributed, every push is authenticated, and signing keys never land on the machine in plaintext. macOS handles this well with two standard mechanisms: SSH agent forwarding (your local private key never touches the remote machine) and per-account GPG signing (each macOS user has their own Keychain and gpg-agent). This guide gives you a one-run setup script, the Xcode source-control decisions once git is wired up, and a short plan-picker for the Figment side.
The goal is to push and pull from GitHub using your laptop's SSH key, without copying the private key onto the rented Mac. With agent forwarding, when the remote Mac needs to authenticate with GitHub the SSH daemon passes the challenge back to your local ssh-agent, which signs it and returns the response. The private key never leaves your laptop.
Configure it once in your local ~/.ssh/config:
Host figment-mac
HostName mac.yourfigment.host # hostname from your Figment quote
User alice
IdentityFile ~/.ssh/id_ed25519
ForwardAgent yes
Verify that your local agent has the key loaded before connecting:
ssh-add -L # should list your public key; if empty, run: ssh-add ~/.ssh/id_ed25519
Then test after SSH-ing in:
ssh -T git@github.com
# Hi alice! You've successfully authenticated…
If the test fails, check that the remote Mac's /etc/ssh/sshd_config contains AllowAgentForwarding yes and that SSH_AUTH_SOCK is set in your remote session (echo $SSH_AUTH_SOCK should print a socket path). The full setup, troubleshooting, and the trust caveat are documented in GitHub's Using SSH agent forwarding guide: only forward to hosts you trust, because a user with root on the remote can use the forwarded socket to authenticate as you for the duration of your session.
For GitHub, your remote URL must use the SSH form (git@github.com:org/repo.git); an HTTPS remote ignores the forwarded agent.
On a shared Mac, each macOS account configures its own user.name and user.email after first login:
git config --global user.name "Alice Developer"
git config --global user.email "alice@yourteam.com"
--global writes to ~/.gitconfig, which is scoped to the current macOS account, not the whole machine. If one repository needs a different identity—for example a contract project under another email—run git config --local from inside that repo; it writes to .git/config and overrides the global value there only.
Confirm the active identity at any time:
git config --list --show-origin | grep user
--show-origin prints the file path alongside each value, making it obvious whether a setting comes from global or local config.
GPG commit signing ties each commit to a verified developer identity. The setup is the same as on a local Mac, with one extra step: install pinentry-mac so gpg-agent can show the passphrase prompt in the remote desktop session (VNC or the browser console) instead of trying to open a native dialog that blocks indefinitely.
# Install GPG and pinentry-mac (run once per macOS account)
brew install gnupg pinentry-mac
# Generate a signing key (ed25519 or RSA 4096)
gpg --full-generate-key
# Note the key ID (long form after the slash on the 'sec' line)
gpg --list-secret-keys --keyid-format LONG
# Example output:
# sec ed25519/3AA5C34371567BD2 2026-11-10 [SC]
KEY_ID=3AA5C34371567BD2 # replace with your own
git config --global user.signingkey "$KEY_ID"
git config --global commit.gpgsign true
git config --global gpg.program "$(which gpg)"
mkdir -p ~/.gnupg
chmod 700 ~/.gnupg
echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent # restart agent to pick up the new config
Export the public key and upload it to GitHub under Settings → SSH and GPG keys → New GPG key:
gpg --armor --export "$KEY_ID" > ~/gpg-public-key.asc
cat ~/gpg-public-key.asc # copy into GitHub's key field
(pbcopy relies on a local display session and is not reliable over SSH; writing to a file and reading it is portable.)
Private key handling: never write a private key to a plaintext file on the remote Mac. If you must move an existing key, export it on your laptop as a passphrase-protected armored secret (
gpg --export-secret-keys --armor "$KEY_ID" | gpg --symmetric --cipher-algo AES256 -o key.asc.gpg), transfer the encrypted file, import it on the remote, and delete the transferred file immediately. Signing certificates (code-signing.p12) are a separate artifact with their own encrypted export, and provisioning profiles are plain.mobileprovisionfiles from the developer portal, not Keychain exports.
Save as git-setup.sh, copy to the remote Mac, run once per new macOS account. set -euo pipefail stops on the first real error so you see exactly where a step fails; the GitHub auth check is explicitly allowed to warn without aborting.
#!/usr/bin/env bash
# git-setup.sh – run as the target developer's macOS account on the remote Mac
set -euo pipefail
: "${GIT_NAME:?Set GIT_NAME, e.g. export GIT_NAME='Alice Developer'}"
: "${GIT_EMAIL:?Set GIT_EMAIL, e.g. export GIT_EMAIL='alice@yourteam.com'}"
echo "==> Configuring git identity"
git config --global user.name "$GIT_NAME"
git config --global user.email "$GIT_EMAIL"
git config --global init.defaultBranch main
echo "==> Checking forwarded SSH agent"
if ! ssh-add -L >/dev/null 2>&1; then
echo "WARNING: no keys in forwarded agent. Run 'ssh-add ~/.ssh/id_ed25519' locally and reconnect." >&2
fi
echo "==> Testing GitHub SSH auth (non-fatal)"
if ssh -o BatchMode=yes -T git@github.com 2>&1 | grep -q "successfully authenticated"; then
echo "GitHub SSH auth: OK"
else
echo "WARNING: GitHub SSH auth did not succeed. Check ForwardAgent in local ~/.ssh/config." >&2
fi
echo "==> Installing GPG tools (requires Homebrew)"
command -v brew >/dev/null || { echo "Homebrew required: https://brew.sh" >&2; exit 1; }
brew install --quiet gnupg pinentry-mac
echo "==> Configuring gpg-agent to use pinentry-mac"
mkdir -p ~/.gnupg && chmod 700 ~/.gnupg
echo "pinentry-program $(brew --prefix)/bin/pinentry-mac" > ~/.gnupg/gpg-agent.conf
gpgconf --kill gpg-agent
cat <<'NEXT'
Done. Next steps for commit signing:
1. gpg --full-generate-key
2. gpg --list-secret-keys --keyid-format LONG
3. git config --global user.signingkey <KEY_ID>
4. git config --global commit.gpgsign true
5. gpg --armor --export <KEY_ID> # upload to GitHub
NEXT
This is an unexecuted example to adapt to your project, not a reported benchmark.
Xcode's built-in Source Control Navigator (⌘-2) is good for reviewing branch history, staging individual lines, and switching branches when you are already in Xcode. It reads the same per-account git configuration as the CLI, so identity and signing settings apply automatically. Apple's Xcode documentation covers the current feature set; the exact capabilities depend on your installed Xcode version, which on an Intel VM must be Xcode 26 or earlier.
For merge resolution over a remote desktop, Xcode's two-pane diff viewer highlights conflict markers with a UI that lets you take left, right, or hand-edit. For automation (pre-commit hooks, CI steps, batch rebases), stay in the terminal—CLI git is faster and composable. Use the UI only when the visual diff actually helps.
| Credential | Correct location | What to avoid |
|---|---|---|
| GitHub SSH private key | Local laptop only, forwarded via agent | Copying the private key to the remote Mac |
| GPG signing private key | macOS Keychain (gpg-agent) on remote Mac | Writing a plaintext export |
App Store Connect API key (.p8) | CI secret store, injected per job | Committing to the repository |
| Git remote password (HTTPS) | git config --global credential.helper osxkeychain | ~/.netrc or ~/.git-credentials |
If your team uses a secret manager (1Password, Vault, AWS Secrets Manager), share only the required secret names; each developer retrieves the values through the manager on the remote Mac. Do not dump the whole environment to a file—it mixes API tokens with innocuous variables and is a common source of accidental leaks. Update the firewall or artifact-store allowlists you control if you tunnel through specific egress IPs; there is no App Store Connect or TestFlight allowlist to add here.
Agent forwarding and a per-user Keychain need a real multi-user macOS environment with inbound SSH, so this workflow sits on a physical M-series host. Entry prices to compare:
Figment's distinct value here is the managed build track: the Managed Build Mac plan ($249/month) includes one M-series Mac, CI setup, backups, monitoring, and 30 minutes of monthly support; Managed Mac Team ($999/month) covers two M-series Macs, two CI runners, team setup, backups, monitoring, and one hour of monthly support. Software licenses, Apple Developer Program membership, and signing certificates stay with you. Confirm macOS version, Xcode version, account count, and SSH policy in your written quote before you port this script across.
Start a configuration at Figment Mac Hosting or jump directly to /mac-hosting/start.
Related: Debug Core Data Issues on a Rented Remote Mac · SwiftData Migration on a Remote Mac · GitHub Actions Self-Hosted Runner on Mac