Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Access rules

rules:
  allow:
    - enabled: true
      order: 110
      operation: [FETCH, PUSH]
      providers: [github/github.com]
      slugs:
        - /myorg/repo-one
        - /myorg/repo-two

  deny:
    - enabled: true
      order: 100 # deny rules with lower order numbers take precedence
      operation: [PUSH]
      slugs:
        - /myorg/archived-repo

Rules are evaluated in order number order (lower = earlier). Deny rules override allow rules at the same order number. The proxy is default-deny: if no allow rule matches, the request is rejected.

operation scopes a rule to PUSH, FETCH, or both. A repo can be open for fetch but restricted for push.

Disabling fetch serving entirely

Access rules gate which upstreams are reachable for FETCH. A separate, coarser switch controls whether server mode serves clone/fetch from its local mirror at all:

server:
  serve-fetch: false # global default; push-only gateway, no local mirror served

providers:
  github:
    serve-fetch: true # optional per-provider override of the global default

Serving fetches is the default and the right one for most deployments — a developer whose remote is the fogwall URL expects git pull to work against it, and taking that away breaks the single-remote workflow. Turn it off when:

  • fogwall is a push-validation gateway that is not meant to be a read path for anything;
  • the mirror holds repositories you would rather not serve from fogwall’s disk at all, regardless of who asks;
  • you want the reachable surface as small as the use case requires.

When disabled, the git-upload-pack capability is simply not mounted (HTTP) and is refused on the SSH transport; a fetch is rejected with a clear git-side message — fatal: remote error: fetches are not served through this gateway — rather than a 404 that reads as a missing repository. Push (receive-pack) is unaffected, and the switch applies to both server mode transports so neither can serve a fetch the other refuses.

This is deliberately not a per-user read-permission model: for a public upstream there is no credential to authorize, and for a private one the fetch already carries the caller’s own upstream credentials, which answers the question authoritatively. Use access rules to gate which repos are reachable, and serve-fetch to decide whether fogwall serves fetches at all. Transparent proxy mode forwards to upstream rather than serving a local mirror, so it is unaffected by this setting.

Dry-run testing rules and permissions

Available since v1.3.0.

Before rolling out a new access rule or permission grant, verify the outcome against the live configuration without waiting for a real push:

POST /api/repos/rules/test
{ "provider": "github/github.com", "owner": "myorg", "name": "myrepo", "operation": "PUSH" }
→ { "decision": "ALLOW", "matchedRuleId": 110, "steps": [...] }

POST /api/users/{username}/permissions/test
{ "provider": "github/github.com", "path": "/myorg/myrepo", "grant": "PUSH" }
→ { "allowed": true, "source": "GROUP", "groupName": "platform-team" }

Both endpoints are read-only evaluations against whatever rules, permissions, and groups are currently loaded — no push is created. source on the permission check distinguishes a direct per-user grant (DIRECT) from one inherited via a permission group (GROUP). These endpoints are dashboard-only (fogwall-dashboard); the standalone server has no REST API.