Secure sign-in
The recommended Git sign-in path for human developers is HTTPS + Git Credential Manager (GCM) — interactive sign-in through your org’s IdP with MFA on every token refresh. SSH is disabled by default for new fremforge orgs; senior developers who specifically need SSH can ask their org admin to re-enable it. This page covers the GCM setup for macOS, Linux, and Windows + a fallback section for SSH and PATs.
Why HTTPS + GCM is the default
| Property | HTTPS + GCM | SSH | PAT |
|---|---|---|---|
| MFA at push | ✅ via your org’s IdP, on every token refresh | ❌ key bypasses MFA | ❌ static bearer |
| Source-IP enforceable by org admin | ✅ Full | ⚠️ Not architecturally possible (Forgejo built-in SSH + load-balancer SNAT) | ✅ Full |
| Credential lifetime | Short-lived OAuth tokens, auto-refresh | Long-lived key (until rotated) | Configurable, often months |
| Setup steps for developer | One-time GCM install + two git config lines | Generate key + upload to fremforge + configure agent | Mint token in UI + paste into git credential store |
| Lost laptop blast radius | Attacker needs your IdP password + MFA — small window | Key file alone is enough — large window | Token alone is enough — until rotation |
GCM is Microsoft’s open-source credential helper; fremforge integrates with it via Forgejo’s built-in OAuth2 provider. Works against Windows, macOS, and Linux developer workstations.
HTTPS + Git Credential Manager (recommended)
Step 1, install GCM
# macOS via Homebrew
brew install --cask git-credential-manager
# Linux (Debian/Ubuntu, Fedora, etc. — see GCM repo for distro-specific paths)
curl -sL https://aka.ms/gcm/linux-install-source.sh | sh
git-credential-manager configure
# Windows — bundled with Git for Windows 2.28+ (re-installer prompt offers GCM)Step 2, configure GCM for fremforge
Run this once per workstation:
# Tell GCM to use the Forgejo/Gitea OAuth provider for frem.sh URLs.
git config --global credential.https://frem.sh.gitProvider gitea
# Use fremforge's pre-registered Git Credential Manager OAuth application.
# Same client_id across every fremforge org — your sign-in still goes
# through your org's own IdP (the per-tenant OIDC source registered at
# /<your-org>/_admin/sso).
git config --global credential.https://frem.sh.oauthClientId e90ee53c-94e2-48ac-9358-a874fb9e0662The OAuth application is the built-in git-credential-manager client that ships with Forgejo — no per-instance registration needed; the same client ID works against every fremforge instance and every Forgejo-based Git host. The client uses PKCE (Proof Key for Code Exchange), so no client_secret is required on the developer’s machine. The loopback callbacks (http://127.0.0.1, http://localhost) are accepted on any port per RFC 8252 §7.3.
Step 3, clone over HTTPS
git clone https://frem.sh/<your-org>/<your-repo>.gitGCM opens a browser tab → frem.sh prompts for your email (so we know which org you belong to) → bounces you to your org’s tenant-scoped sign-in page → only your org’s IdP button(s) are shown → enter password + MFA at your IdP → browser returns to GCM → token cached. Other tenants’ IdPs are never visible. Subsequent clones, fetches, and pushes within the token’s lifetime are silent.
Access tokens last 8 hours (one working day) — within that window every git push is silent. Refresh tokens last 30 days and rotate on each use, so the next push after token expiry transparently refreshes without a browser prompt unless 30 days have passed since the last sign-in. After 30 days of inactivity, the next push pops the browser again and your MFA fires via your IdP.
Step 4, optional — set sensible defaults
# Cache the OAuth token between sessions instead of re-running the
# browser flow every laptop reboot. GCM stores it in the OS keychain
# (macOS Keychain / Windows Credential Manager / Linux libsecret).
git config --global credential.credentialStore gpg # Linux only
git config --global credential.guiPrompt true # macOS / LinuxFallbacks
Personal access token (CI bots and scripts only)
PATs are static bearer credentials with no MFA. They’re fine for unattended automation; never for human push.
# 1. Mint at frem.sh/-/user/settings/applications
# 2. Set expiry to the shortest practical value (30 days for routine,
# 90 days for stable CI). If your org admin has set a max lifetime
# policy, the mint page caps the dropdown automatically.
# 3. Use as the password for HTTPS clone:
git clone https://<your-username>:<pat>@frem.sh/<org>/<repo>.git
# Or via GCM's "store in keychain" path so you don't bake it into URLs:
git -c credential.helper=store clone https://frem.sh/<org>/<repo>.git
# Enter username + paste PAT when prompted; cached in ~/.git-credentials.Forgejo Actions OIDC tokens (CI workload identity, no static creds)
For CI/CD that deploys to AWS / Azure / GCP / T Cloud, prefer federated identity over PATs. Forgejo Actions ships an OIDC issuer at https://frem.sh/api/actions/.well-known/openid-configuration; configure your cloud provider’s IAM to trust it. See Runner OIDC for the per-cloud trust-policy templates.
SSH (only when your org admin has explicitly enabled it)
New fremforge orgs have SSH disabled by default. If your org needs SSH (legacy CI, strong developer preference for the SSH-key flow):
- Org admin visits
<your-org>/_admin/auth-policyand unchecks “Disable SSH protocol — HTTPS only for this org” — accepting the documented limitation that IP allowlist doesn’t apply to SSH. - Members add SSH keys at
frem.sh/-/user/settings/keysand configure their~/.ssh/config:
Host frem.sh
Hostname ssh.frem.sh
Port 443
IdentityFile ~/.ssh/id_ed25519- Use hardware-backed keys where possible (
ssh-add --apple-use-keychainon macOS for Touch ID;ssh-keygen -t ed25519-skfor FIDO/YubiKey on Linux). See the hardware-backed SSH section below.
Hardware-backed SSH keys (for orgs that have re-enabled SSH)
If your org admin has re-enabled SSH and you do need to use it, hardware-backed keys are mandatory-best-practice. The org-level “Require hardware-backed SSH keys” policy refuses any key not in the sk-* algorithm family at registration time.
macOS — Secure Enclave
ssh-keygen -t ed25519 -C "your-name@your-org" -f ~/.ssh/id_ed25519
ssh-add --apple-use-keychain ~/.ssh/id_ed25519Touch ID prompts on every push if the macOS keychain hasn’t recently unlocked the key. For pure Secure-Enclave residency (key generated and held entirely inside the chip), use Secretive.
Linux — YubiKey / FIDO authenticator
ssh-keygen -t ed25519-sk -C "your-name@your-org" -f ~/.ssh/id_ed25519_sk
ssh-add ~/.ssh/id_ed25519_skRequires OpenSSH 8.2+ (Feb 2020) for ed25519-sk; ecdsa-sk is the fallback on older distros.
Windows — TPM-backed via WSL2 / KeePassXC
Native Windows OpenSSH doesn’t expose the TPM directly. Two paths:
- WSL2 — follow the Linux flow inside WSL2.
- KeePassXC / 1Password SSH agent — both hold keys protected by Windows Hello biometric.
Decision tree
Are you a human developer pushing code daily?
├── Yes → HTTPS + GCM (the recommended default; no SSH key needed)
│ ├── If your org has re-enabled SSH and you prefer it → hardware-backed SSH key
│ └── If you specifically need a static credential → PAT with 30-day expiry
└── No, I'm a CI bot or script
├── Cloud-deploying → Forgejo Actions OIDC token (no static cred)
└── Other → PAT with tight scope + short expiryWhat NOT to do
- Long-lived PATs in git config files /
.netrc. Static bearer credentials with no expiry are the worst auth pattern. Use GCM for humans, OIDC tokens for CI, and short-expiry PATs for legacy bots. - Plain
ssh-keygen -t ed25519without hardware backing or org-required. The key sits in~/.ssh/; lost laptop = compromised key for the lifetime of the key. - Skipping MFA via “always-trust SSH key” patterns. If your org needs IP-allowlist-grade enforcement, that means HTTPS — fremforge’s IP allowlist is real-time on HTTPS and not architecturally possible on SSH.
- Re-enabling SSH because “it’s faster”. The setup-friction difference is negligible after the first day; the security-posture difference is real.
Org admin reference
If you’re an org owner setting policy:
- Authentication policy admin guide — SSH-disable toggle, hardware-backed SSH key requirement, SSH certificate authority (folded in 2026-05-26), max PAT lifetime, allow repo deploy keys toggle, signed-commits, IP-allowlist scope + audit-only preview