Project
Security
What a profile can do, what the log redacts, what save refuses to export and how to report a problem.
A .glaze profile runs commands in your shell with your privileges. That is the whole point of the tool, so “a profile can run commands” is not a bug report, it is the feature list. What is a bug is a profile that does something its text does not say, a parser that falls over on hostile input or a save that writes your secrets into a file you then commit. This page draws that line, says what Glazier does to stay on the right side of it and tells you how to report it when it does not.
Profiles execute commands by design
The commands, hooks and options of a profile go to your tmux server and run in your shell. To apply an untrusted profile is to run an untrusted script. Read a profile before you run glaze up on it, the same as you read a shell script that you downloaded.
These reports are in scope:
- A way to make a profile do something that its text does not say. Examples are command injection or argument injection through variable expansion, through a template function or through an escaping bug in the tmux commands that Glazier builds.
- A panic, a hang or memory exhaustion in the parser on a malformed profile, a
--varvalue, a--var-fileor aGLAZE_ENV_*variable. These surfaces are fuzzed in CI. - A
saveoutput that contains an environment value, a command, a hook or an option from the live session.
Out of scope: a profile that runs the commands that it declares.
What the log redacts
A command or a hook can contain a secret from a variable, so Glazier limits what it prints.
| Where | What shows |
|---|---|
| Default log level | Only the number of commands that up runs in each pane. |
--debug | Each tmux command that Glazier sends, and the text of each pane and session command and hook. |
| An env value, at every level | <redacted>. The key stays. |
| An error from a tmux command | The command that failed, with each env value as <redacted>. |
Check --debug output before you share it.
warning
tmux gets each env value as a command-line argument. Another user on the same host can see it with ps for a moment. Glazier does not fix this; it documents it. Do not put a secret in envs on a shared host.
What save refuses to export
glaze save captures the structure of a session: the session, window and pane names, the starting directories, the focus and the layout. It does not export pane commands, environment variables, hooks or tmux options. See glaze save for the flags and Save a session for the workflow.
This is a decision, not a gap. Each of the four is a footgun:
- A command runs again on the next
glaze up. A destructive command from a forgotten pane deletes a filesystem or overloads a database on replay. tmux also cannot report what a pane runs, only the name of its foreground process. - A hook is a command bound to an event. It carries the same risk as a command, deferred and less visible.
- Glazier can read environment variables only as the full session environment. That environment includes the secrets from your shell, for example tokens and keys. An export writes those secrets into a file that you could commit.
- Options read back as effective state. They mix your
tmux.confand your manual changes with the values that Glazier set. To apply that state again onupgives unwanted results.
The common thread is provenance. tmux reports effective state, not what Glazier set. Anything that Glazier reads back that way leaks configuration or secrets, and anything that is a command is an execution risk on replay. All four stay fully supported in up; save simply never writes them. A save output that contains one of them is a valuable report.
The parser limits
The parser puts a limit on the resources that a profile can use, so a hostile profile cannot crash Glazier or fill the memory. See Limits for the diagnostics that each limit gives.
| Limit | Value | What it stops |
|---|---|---|
| Nesting depth | 256 levels of brackets, braces, parentheses and strings | A stack overflow in the HCL parser, which no recovery catches. |
| Locals size | 1 MiB of string bytes plus elements, for all locals together | A local that repeats a large value many times. |
warning
A nested for expression is not bounded. HCL gives Glazier no way to count the evaluation steps. Read an untrusted profile before you run glaze up, glaze format or glaze down on it.
The paste buffer
Glazier does not type pane commands into the pane. It loads them into a tmux paste buffer with a random name, then types one line that tells the shell to eval the buffer. See Commands for the mechanism and Run commands reliably for the reasons.
The trust model does not change. The eval runs only the commands from your profile. Earlier versions of Glazier typed the same commands into the pane, so a person who can change your profile could always run commands in your panes.
Glazier sends the buffer to tmux on stdin, so the commands do not appear in the process list. The first line of the buffer deletes the buffer. Only a client with access to your tmux socket can read or change a buffer, and such a client can already type into your panes.
No network access
Glazier talks only to a local tmux socket. It makes no network connections of its own.
Supported versions
Glazier is pre-1.0. Security fixes go to the latest released v0.x minor. There are no long-term support branches yet.
| Version | Supported |
|---|---|
latest v0.x | Yes |
| older | No |
Report a vulnerability
Report a security problem in private. Do not open a public issue for a problem that someone can exploit.
- Open a private security advisory on GitHub. On the repository, this is “Security”, then “Report a vulnerability”.
- If that is not available, contact the maintainer in private through GitHub.
- Include the affected version, a minimal proof of concept and the impact that you saw.
I will acknowledge the report, investigate it and agree a fix and a disclosure timeline with you. The full policy is in SECURITY.md.