Git Credential Settings¶
New here? Git workflows in Muppy explains the model in one page — why it works this way, and which tokens to create.
These settings tune how an App Server obtains git credentials — the approval windows, the login UX, and the policy that decides what a token is allowed to be used for. They are global (platform-wide), set in Settings → Muppy → Git credential helper.
For how tokens are resolved and how muppy-git-login is used on a box, see the
Git Tokens guide. This page is only about the tuning knobs.
The model in one paragraph¶
A login names an identity: it says which user an App Server acts as. It releases no credential. Each git operation asks for its own authorization — once, or for a window — and blocks while it waits. So the thing being approved is held by the command that asked for it: there is never an approved credential sitting on a box waiting for somebody to spend it.
A session has no lifetime. Its age is irrelevant because it grants nothing. It ends
when it is closed: by muppy-git-logout, by another user claiming the box, or by the
nightly job.
The windows¶
| Setting | Param (ir.config_parameter) |
Default | What it controls |
|---|---|---|---|
| Window for a write-capable token | muppy_git.write_capable_window_minutes |
15 min | How long an authorization served by a token that can write stays open, counted from the approval. |
| Window for a read-only token | muppy_git.read_only_window_minutes |
480 min (8 h) | Same, for a token that cannot write. |
The axis is the capability of the token being served, not the scope of the operation
asking. That distinction has one case, and it is the case that matters: on a box whose
only credential can push, even a git pull is served by that token — so it takes the
short window.
That discomfort is deliberate
A box with only a read-write token will prompt you roughly twice an hour. Creating a read-only token is what makes it stop. Every other decision in this system pushes the same way; making this comfortable would remove the reason to do the work.
The window starts when you approve, not when the command ran
You approve two minutes after the push started, so the window ends two minutes later than the command did. The clock starts on the click.
The policy on repository scoping¶
| Setting | Param | Default | What it grants |
|---|---|---|---|
| Repo-scoped read-only tokens earn free reads | muppy_git.repo_scoped_ro_free_read |
on | A read-only token limited to one repository is served with no session and no approval at all. |
| Repo-scoped read-write tokens may slide | muppy_git.repo_scoped_rw_sliding |
on | A read-write token limited to one repository may open a sliding window — one that restarts on each of the user's own pushes, so it follows the work and closes shortly after it stops. |
Both answer the same question: how far do you trust a repository's boundary?
What a free read actually guarantees
At worst: a full read of that one repository. It is contained against writing and
against other repositories — not against the repository's own contents. A box
cloned with --depth=1 on one branch holds a fraction of what the token opens: every
branch, all history, all tags. On a monorepo that depth is breadth.
Turn the setting off when a repository holds more than a developer should see. That row then falls back to a prompt, exactly like a wide read-only token.
It also decides how much of your traffic is observable
An approval taken outside the box is how you learn a compromised box tried to use your credential — it can only ask, and asking is visible. A free read asks nothing, so it is the one path that could be used without anyone hearing about it. Off, every read goes through an approval and nothing at all is served unseen. See Git workflows in Muppy.
A token that can push anywhere never gets a sliding window, whatever these are set to. That is not an organizational judgement.
A read never extends a sliding window either — a read cannot be told apart from background traffic, so an open editor would otherwise hold the window open forever.
Holding a box, and taking it¶
| Setting | Param | Default | What it controls |
|---|---|---|---|
| Takeover cooldown | muppy_git.takeover_cooldown_minutes |
15 min | How recently a session may have been opened and still be claimed with muppy-git-login --force. |
| Nightly logout hour | muppy_git.nightly_logout_hour |
4 | Local hour, in the session user's timezone, at which an open session is closed. -1 disables it. |
One session is open per App Server at a time. A second user is refused and told who holds
it; --force claims it, and the incumbent is notified. The eviction happens when the
claiming user approves, not when they type the command — so a request nobody validates
leaves the incumbent in place.
The cooldown breaks the ping-pong: two people cannot take a box from each other at
machine speed. Coordinated developers have a better protocol anyway — the incumbent runs
muppy-git-logout.
The nightly logout does two things. It bounds how long an abandoned box can prompt its owner — the one real risk of a session that grants nothing is that a push triggered at 9am arrives while you are at your desk and you approve it thinking it is your IDE. And it makes a session end on its own, so a colleague who forgets to log out on Friday no longer blocks the box until somebody evicts them.
Waiting¶
| Setting | Param | Default | What it controls |
|---|---|---|---|
| Approval deadline (device code) | muppy_git.login_device_code_ttl_seconds |
600 s | How long a pending login may be approved before it lapses. |
| Login wait | muppy_git.login_wait_seconds |
120 s | How long muppy-git-login waits for its approval before giving up. |
| Blocked git operation wait | muppy_git.credential_wait_seconds |
120 s | How long a blocked git operation waits — and the lifetime of the pending authorization it is waiting on. |
| Login poll interval | muppy_git.login_poll_interval_seconds |
4 s | Poll cadence. |
| Provisioning grant lifetime | muppy_git.provisioning_window_minutes |
20 min | Window of the short, owner-approved read grant used for the first clone when a box is provisioned. |
The last two columns of the third row are one value on purpose: when the helper stops waiting, nobody is holding that authorization any more, so it must lapse rather than sit there. Leaving it pending would be exactly the approval-waiting-for-a-taker this design removes.
The device-code deadline answers a different question from the two waits — how long do you have to reach a browser and approve — which is why it is ten minutes and they are two.
The Git Operations Log¶
| Setting | Param | Default | What it controls |
|---|---|---|---|
| Keep git operations for | muppy_git.operation_log_retention_days |
90 days | How long a row stays in the log before a nightly job deletes it. |
The log keeps one row per transition on the git path — a login approved or refused, an authorization asked for and served, an introspection. It is the only place that keeps what nothing else does: a session and an authorization each carry their current state, so the attempts that led nowhere live only here.
Shortening this shortens how far back "was anyone trying to push from that box?" can be answered. What it costs is small: a few hundred bytes a row, except an introspection, which carries the provider's reply and runs to about a kilobyte.
One rule for every kind of row. If the volume ever justifies it, the shape to reach for is ageing out the API trace while keeping the event — the bulky part loses its value in days, the fact does not.
Provider connections¶
| Setting | Param | Default | What it controls |
|---|---|---|---|
| Connection idle ceiling | muppy_git.connection_idle_minutes |
120 min | The longest keep alive a user may choose when connecting a Git provider. |
Connecting a provider gives Muppy read-only access to its API on your behalf — to list and check your tokens. The connection is never handed to a box, and it closes on its own once idle, so Muppy is not left holding standing access to your account.
Users may always ask for less than this ceiling, never more; it is enforced server-side as well as in the wizard. Lowering it applies to connections already open, at the next sweep — tightening does not wait for anyone to reconnect.
This is also why re-checking your tokens is a button rather than a nightly job: a dead or fine-grained token can only be read through such a connection, and at 03:00 there is never one.
The policy switch¶
| Setting | Param | Default |
|---|---|---|
| Require a read-only token for read access | muppy_git.require_read_only_token |
off |
One switch, three effects, all in one direction — a credential that can write is never used where reading is enough:
- Dev boxes — a read may be served by a read-write token (off), or only by a read-only one (on).
- Deploys — a deploy runs with whatever token is configured (off), or requires a read-only one (on).
- Remote URLs — any token may be embedded at provisioning (off), or only a read-only, repository-scoped one (on).
Off matches the behaviour of an estate that has not opted in, so upgrading changes nothing. Full page: Read-only token policy.