Branch protection now supports per-ref policies, letting you decide exactly which branches, tags, or namespaces a signed token can write to.
The new refPolicies option is an ordered list of rules. The first matching rule wins, patterns
without a refs/ prefix are treated as branch names, and a final * rule can turn a token into a
deny-by-default allowlist.
const url = await repo.getRemoteURL({
permissions: ['git:read', 'git:write'],
refPolicies: [{ pattern: 'main', ops: ['no-push'] }],
});url = await repo.get_remote_url(
permissions=["git:read", "git:write"],
ref_policies=[
{"pattern": "main", "ops": ["no-push"]},
],
)url, err := repo.RemoteURL(ctx, storage.RemoteURLOptions{
Permissions: []storage.Permission{storage.PermissionGitRead, storage.PermissionGitWrite},
RefPolicies: storage.RefPolicyList{
{Pattern: "main", Ops: storage.Ops{storage.OpNoPush}},
},
})This rejects writes to main while leaving other branches writable by the token. The same policy
model is also available on ref-mutating REST calls like createBranch, merge, createCommit,
tags, and notes.
no-force-push is still available for blocking non-fast-forward updates, and no-push now blocks
any update to the matched ref. The older top-level ops option on remote URL methods still works,
but refPolicies is the preferred way to define branch protection going forward.