type: service
status: active
timestamp: 2026-06-24
tags: [service, git-host, mirror, backup, azure-devops, microsoft, free-tier]

Azure DevOps Repos — push-mirror target for chirag127 + chirag127

Git mirror host #5 — unlimited private repos, 5 free users, push via GH Actions

Azure DevOps Repos — push-mirror target

Role

Azure DevOps Repos is mirror host #5 in the 6-host DR strategy. Provides Microsoft-backed corporate + geographic diversity. Unlimited private Git repos, 5 free users, excellent API.

⚠️ Global PAT Retirement (December 1, 2026)

Azure DevOps “global” Personal Access Tokens (valid across all orgs) are being retired on December 1, 2026. You must use org-scoped PATs instead.

When generating the token: on the “Organization” dropdown select your specific org (e.g. chirag127), NOT “All accessible organizations”.

Free Tier

LimitValue
ReposUnlimited private Git repos
Storage<10 GB/repo recommended; 250 GB hard limit
Artifact storage2 GiB free per org
Users5 free Basic-access users
CI Pipelines1 MS-hosted job, 1,800 min/month
Pull mirroring❌ No native pull-from-GitHub mirror

Authentication

FieldValue
Token typePersonal Access Token (PAT) — org-scoped
Token URLhttps://dev.azure.com/{org}/_usersSettings/tokens
Required scopeCode: Manage (includes Read + Write + Create repos)
Env var namesMIRROR_AZURE_DEVOPS_TOKEN, MIRROR_AZURE_DEVOPS_ORG, MIRROR_AZURE_DEVOPS_PROJECT
Git URL formathttps://anything:[email protected]/org/project/_git/repo
API authBase64-encode :TOKENAuthorization: Basic <base64>

How to get the token

  1. Log in at https://dev.azure.com
  2. Create or use an existing organization (e.g. chirag127)
  3. Create a default project (e.g. mirrors or oriz)
  4. Click your avatar (top-right) → Personal access tokens URL: https://dev.azure.com/{org}/_usersSettings/tokens
  5. Click + New Token
  6. Name: oriz-mirror-bot
  7. Organization: select your org specifically (NOT “All accessible organizations”)
  8. Expiration: 1 year
  9. Scope: Code → Manage (this includes read+write+create)
  10. Click Create — copy immediately, shown once
  11. Note your org name and project name
  12. Store as chirag127 org-level GitHub secrets (token + org + project). Full loop: runbooks/platform/mirror-all-hosts-setup.md Step 2.

API — Create Repo (idempotent)

# First get project ID
PROJECT_ID=$(curl -s \
  -u ":${MIRROR_AZURE_DEVOPS_TOKEN}" \
  "https://dev.azure.com/${MIRROR_AZURE_DEVOPS_ORG}/_apis/projects/${MIRROR_AZURE_DEVOPS_PROJECT}?api-version=7.1" \
  | jq -r '.id')

# Create repository
curl -s -X POST \
  -u ":${MIRROR_AZURE_DEVOPS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d "{\"name\":\"${REPO_NAME}\",\"project\":{\"id\":\"${PROJECT_ID}\"}}" \
  "https://dev.azure.com/${MIRROR_AZURE_DEVOPS_ORG}/${MIRROR_AZURE_DEVOPS_PROJECT}/_apis/git/repositories?api-version=7.1" \
  || true  # 409 = exists — fine

Note: Azure DevOps uses Base64-encoded :TOKEN for Basic auth:

# Equivalent with -u flag (curl handles encoding automatically)
curl -u ":${MIRROR_AZURE_DEVOPS_TOKEN}" ...

Rate Limits

Mirror URL pattern

https://anything:${MIRROR_AZURE_DEVOPS_TOKEN}@dev.azure.com/${MIRROR_AZURE_DEVOPS_ORG}/${MIRROR_AZURE_DEVOPS_PROJECT}/_git/${REPO_NAME}

Pull Mirror — NOT available

Azure DevOps has no native pull-mirror-from-GitHub. Push-mirror via GitHub Actions is the only automated option.

Failure modes

SymptomCauseFix
401 UnauthorizedPAT expired or wrong orgRegenerate org-scoped PAT
403 ForbiddenPAT missing Code: Manage scopeRegenerate with correct scope
404 Not FoundRepo/project doesn’t existRun repo-creation script
429 Too Many RequestsRate limit hitAdd sleep 1 between API calls
Push fails on global PATGlobal PATs retired Dec 1 2026Use org-scoped PAT

Cross-refs


Edit on GitHub · Back to index