Skip to content

Who may continue a custom session branch?

A session can name its own branch (branch on POST /api/sessions). A new session continues that branch when it already exists. Outside hangar/session/ the name is predictable. So another person's sandbox could create it first, plant commits, and have your agent build on them. This page says how hangar stops that. It is part of the security model.

What the gateway records

The git gateway reads every push before it goes upstream. When a push creates a branch, the gateway notes the person its sandbox belongs to. It does this only for a ref update from the zero id that upstream accepted.

A job's branch is recorded the same way: hangar pushes it with a delivery grant, through the gateway, so the job's person is the creator. A job delivered in direct mode records its person after the push, unless a record exists already. A sandbox with no person, such as a GitHub issue's job, is recorded as nobody's.

What a new session decides

When a session names a branch outside hangar/session/, hangar looks up who created it on that repo:

The branch was The session
Created through the gateway by another person's sandbox Is refused, with session.branch_refused in the audit log
Created by a sandbox with no person Is refused the same way
Created by a sandbox of the same person Starts, and continues the branch
Never seen created by hangar Starts, and continues the branch, as before

The last row keeps "continue my branch" working. It covers a branch a person pushed from their own machine, and one created before hangar kept records.

The admin override

An admin who means to take such a branch passes "take_branch": true. The session starts, and the audit log gets session.branch_override with the creator's person and sandbox. A member who passes it is refused with 403, and the attempt is audited as session.branch_refused.

From then on

The session holds its branch as soon as it is created. The gateway refuses any other sandbox that tries to create the branch, or one that would block it. A job's branch is held the same way from the moment the job is submitted.

What this doesn't cover

  • Pushes outside the gateway. A direct-mode sandbox holds the git token and pushes without a record. A person who pushes a branch from their laptop leaves none either. Both look like "never seen created", so a session continues them.
  • A record outlives a deleted branch. If someone deletes the branch on GitHub, the old record still decides. An admin takes it with take_branch.
  • Two sessions on one branch. A second session may still name a branch another session uses, as before. An admin's session can do that, since only admins name branches today. Both sessions' sandboxes may then push it.