GeezerVisonThe World Wide Web, restored to 800 pixels of glory. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Home|About|Gaming cabinet|Archives|How it works|Starter sites | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
GeezerVison is showing docs.pullfrog.com — Security - Pullfrog Pullfrog gives agents a real shell, git and the GitHub API, and still keeps secrets and credentials out of their reach. Independent layers block the usual prompt-injection goals: reading API keys, stealing tokens and pushing malicious code.
Most of these layers defend against untrusted authors: people who open issues, pull requests and comments without write access. That exposure is largest on public repositories. System promptEvery run carries a system prompt that tells the agent not to reveal secrets or commit them, and to refuse any request it suspects is malicious. The prompt marks where the system section ends and the task begins, and the task cannot override the system section.Untrusted input isolationIssue and pull request bodies are the main prompt-injection vector, so Pullfrog does not inline them as context. The agent gets the event metadata it needs, such as the title, branch and author, and fetches bodies through a Pullfrog tool, so that text reaches the model as tool output, not as instructions. The exception is the text that asks Pullfrog for something: a comment, issue, pull request or review that mentions@pullfrog becomes the agent’s task.
Secret maskingPullfrog registers every secret with GitHub’s secret masking, so a secret printed by accident shows as*** in the Actions log.
Secret isolationA run gets secrets from two places, and neither one exposes them by default:
Shell environment scrubbingThe Shell isolation toggle in the repo console’s Security card decides what environment shell commands get. It works the same way for every agent.![]() ![]()
restricted, whatever the setting.
Lifecycle scriptsSetup, post-checkout and pre-push scripts get the same environment and the same sandbox as shell commands. You write these scripts, but the code they call is not always yours: on a pull request from a fork, a pre-push script ofpnpm test runs the contributor’s tests.
Default allowed variablesThese variables reach shell commands automatically. Every other variable is blocked unless you add it to the environment allowlist. Prefix-matched. Every variable with one of these prefixes passes, except a name that ends in one of the sensitive suffixes above.
System variables
Runner image toolchain variables Environment allowlistThe Environment allowlist field in the Security card passes extra variables to shell commands, one name per line. Use it for variables your build needs, such asDATABASE_URL or NPM_TOKEN. Every shell already has a read-only GH_TOKEN; list GH_TOKEN or GITHUB_TOKEN only when a prompt needs gh to write, and the listed one replaces it.
Listed values reach agent shells in plaintext, so list only variables you are willing to expose to any prompt that runs in the repository. Allowlisting GITHUB_TOKEN or GH_TOKEN gives shell commands the workflow token’s permissions; narrow them with the permissions: block in pullfrog.yml.Filesystem sandboxIn CI each shell command also runs in a mount namespace that hides or freezes three kinds of path. This applies whether shell isolation is on or off.
.git, including .git pointer files in worktree and submodule layouts, and they cannot read .git/config or /var/lib/pullfrog/. Pullfrog’s own file-upload tool only uploads regular files from the repository or a temp directory.
Commands an agent starts itselfIn CI on Linux, unlessshell is enabled, everything Pullfrog starts outside the sandbox, the agent process included, only finds commands in directories that only root can write, plus its own node, npm and npx. This stops anything installed from the agent’s shell from running outside the sandbox. Shell commands keep your full PATH, so installs work as usual.
A local MCP server or formatter configured in your repo starts from the agent process. If its command lives somewhere else, such as uvx in ~/.local/bin, give the command as an absolute path.
OpenCode’s file tools refuse a path that a symbolic link leads outside the repository and the temp directories. Use the shell tool for a file reached that way.
Self-hosted runnersPullfrog runs on self-hosted runners. The shell sandbox needsCAP_SYS_ADMIN, which runner kinds expose differently:
sudo, env, unshare, setpriv and bash from a PATH directory that root owns and no other user can write, because anything a shell command can write it could replace. If unshare or setpriv lives only in a user-writable directory, such as a Homebrew prefix, shell commands stay off for that run and the log says why. /usr/bin and NixOS’s /run/wrappers/bin and /run/current-system/sw/bin qualify.
Subscription credentials need passwordless sudo to set up /var/lib/pullfrog/. On a runner without it, Pullfrog skips them and uses an API key if one is available.
What the container fallback guaranteesA shell command still cannot read another process’s environment variables, reach Pullfrog-managed files, undo the filesystem protections or signal the Pullfrog process. The kernel blocks cross-namespace environment reads on its own. One thing differs: inside a user namespace the container’s/proc cannot be replaced, so a shell command can see which processes run and their command lines. Pullfrog never puts credentials on a command line.
When it does not engageThe fallback needs a pod that may create user namespaces and a node kernel that permits them. It does not engage in these cases:
gh tool, and the log names these causes. The agent can still read and edit files, commit, push, review and comment. It is told why it has no shell, and says so when that leaves a result unverified, such as a fix whose tests it could not run. Pullfrog never runs shell commands unsandboxed in CI.
Short-lived tokensPullfrog uses GitHub OIDC to get installation tokens that are scoped to the repository and expire on their own. Pullfrog also revokes them at the end of each run. The git token is never in the agent’s environment or in.git/config, and the .git directory is read-only to shell commands. Git authenticates through ASKPASS: a localhost helper hands git a code that is valid only for one operation and revokes it when the operation ends, and it answers only for GitHub, so git configuration that points a fetch or push at another host gets no credential. If anything replays a code after that, Pullfrog revokes the GitHub token at once.
Permission checksPullfrog checks the GitHub permission of the person who triggered each run. Users with write, maintain or admin access are collaborators; everyone else is a non-collaborator. Repo admins decide which non-collaborator events start a run:
restricted shell, with a scrubbed environment, and cannot push code, however the repository is configured: its git token is read-only. A review bot on a pull request that Pullfrog opened counts as the repository’s own automation, so Pullfrog still pushes fixes for its review.
Signed commitsSigned commits are free on personal accounts and included in the Organization plan. With the setting on, Pullfrog creates commits through the GitHub API, and GitHub signs them with its own key. They show as Verified and satisfy a “require signed commits” branch protection rule, which otherwise rejects every push from an agent. Turn it on per repository with Signed commits in the Security card. Pull requests from forks and content tracked by Git LFS fall back to ordinary unsigned commits.Code pushesRepo admins set Code pushes in the repo console’s Security card. The setting applies to the whole repository, and an explicitpush: input in the workflow overrides it.
These settings control what the agent publishes, not local edits or local commits. They apply to the Pullfrog runtime, and a modified workflow can bypass them. A custom GH_TOKEN keeps the permissions its owner granted; Pullfrog does not narrow it. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| You are visitor 01402503 — GeezerVison does not store the pages you look up. Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required. |