op-jacket - description of the usage of a jacket (or helmet) under op
op-jacket [-C config] [-f file] [-g group] [-P pid] [-R root] [-u user]
mnemonic program euid:egid cred_type:cred
A "jacket" completes an additional step in the authorization of a priv-
ilege escalation which op has already authenticated (and given prelimi-
nary authorization). A "helmet" does exactly the same operation, but
it exit(3)s after the authorization, while the jacket waits for the
escalated command to exit to cleanup afterwards.
For the purposes of this document we'll examine the jacket case, a hel-
met just doesn't provide any cleanup, but takes the same steps as a
jacket. All such programs support jacket mode, some do not support
helmet mode because they require a cleanup step.
While a jacket may be run from the command line for testing, it is
mainly run from op(1l). This is because op always provides the command
line options which describe the current escalation context. That's
what allows the jacket to continue the authorization of the given esca-
lation. Providing all these options from a script is much harder,
mostly you have to make some of them up (which weakens the credential's
The output of each process is a stream of op-specific commands, which
any other application would have no way to parse or understand.
Every jacket takes the same options. Detailed specification of the
authorization required is always sent via the environment. Since op's
configuration markup is declarative, this best maps that style to the
task at hand.
Which op configuration file provided the specification for the
rule. This is usually an absolute path to the configuration
file that contained the definition of the rule op is using. It
won't be an absolute path if the access file is configured as a
relative path. It may not be visible if the jacket chroot's, as
the escalated process does (see -R below).
This could contain mk(1l) markup or other meta information. The
only sure thing about the file is that it is relatively secure.
If the access is in sentinel mode, the jacket may not even be
allowed to open the file (this is intended behavior).
The file specification given to op, as an absolute path. If you
have to check something about the contents of the file, this is
the place to do it.
The group specification given to op.
Print a brief command-line help message. Never used by op.
Print only a brief description of the environment parameters.
Never used by op. Some jackets may not support this option.
The process-id of the jacketed process (only as a jacket). This
is how a jacket knows that it is in "jacket mode". If no -P
option is presented it should assume helmet mode and exit EX_OK
(0) to allow op to finish the escalation process.
The directory we chroot(2)'ed under. Only set when a chroot is
requested. To be clear, the jacket must chroot, if is needs to
see the filesystem as the escalated process does.
This might also be used to abort any authorization that requires
access to the superior environment. For example, for logging
The user specification given to op.
Output only the version of the program, then exit. Never used
The requested mnemonic from op's command line.
The program mapped from the mnemonic. This will be given to
execve(2) if the escalation is allowed. Repeating checks that
are easy with %_ or !_ is never a good idea. Hiding checks
(that should be in the configuration) in a local jacket is Poor
Form, at best. In light of the root option, there are three
unique case to code:
The internal echo function is represented as a program that is
just the word "echo". No actual external program will be exe-
Since the jacket is run outside of the new root: when a chroot
is in effect (under -R) the path to the actual executable must
be computed by prepending the specified root. The signed jacket
has the correct code to do this.
Otherwise the program path is correct as given.
The computed effective uid and gid that will be assigned before
the execution of the process.
The credential type that granted access (groups, users, or net-
groups), plus the matching element. The pseudo cred_type "test"
is used by my test drivers; always with the number of the test
as the cred.
op accepts several commands from stdout of every jacket (helmet) exe-
cuted. It reads these commands as they are flushed from the jacket
process. See op(1l) under API for a complete description.
Listed below are the jackets I use. Feel free to submit others that
you believe are useful.
Apply a list of jackets to this escalation. This provides an
environment that allows each listed jacket to provide a "thumbs
up" (or down) for the escalation. Only when all allow the esca-
lation will it occur. Each is also given an exit code to pro-
cess. This is actually a pretty hard trick, so you'd better be
Checks for the existence and value of environment variables.
The values are checked against an RE match (ENVAUTH_VAR_name=RE)
or against a non-match (ENVAUTH_NOT_name=RE).
Check that the escalated program is white-listed.
Forwards the original ssh-agent environment to the escalated
process by creating a socket that proxies all connections. This
avoid the checks in OpenSsh that think that file permissions are
not good enough.
Set environment variables to the shell evaluation a command.
Compare the proposed executable to a checksum or hash value.
Allow an authentication stamp to hold credentials for future (or
parallel) escalations. This is very much like sudo's "times-
tamp" feature. This requires that the command below be run as
the superuser at system boot:
See stampctl(8l) for details on usage.
Check the current time. A specification my use any strftime(3)
format to produce an inequality that must be true. Some com-
mands may only be allowed after hours, or on weekends. This is
out-sourced from op so that local policy can be detailed. Com-
mands may be limited to a box with $TIMEBOX_INSIDE or outside a
box with $TIMEBOX_FORBID.
Allows an escalated process to see the client's wrapper diver-
Does the xauth(1) copy to allow an escalated process to access
the original login's $DISPLAY. The the home directory for the
logins is the same no action is taken.
Output the version and environment parameters for the environ-
ment authorization jacket.
( sleep 5 & \
ENVAUTH_VAR_XTERM_LOCALE=. ENVAUTH_NOT_XTERM_LOCALE='^polish$' \
exec /usr/local/libexec/jacket/envauth -P $! -- \
true /usr/bin/true 0:0 test:case1 )
Run a test for the environment authorization jacket, which
should succeed, for me, since the value of $XTERM_LOCALE is "C"
not "polish". This fails when the variable is unset as well.
Limit this escalation window from midnight to before 05:00, from
the op configuration file.
/usr/local/sbin/stampctl -M ecru/$l -E 10m TTY=$y ; ...
Enable an authorization stamp for 10 minutes. Note there is
usually a link from sbin/stampctl to the libexec/jacket/stampctl
location. This makes it much easier for the admin to find the
This escalation requires that the login be on the same control-
ling tty as when the stamp was created for the "ecru" facility.
Forward the current X display to the inferior process. This
does write in the home directory of the target login, but that's
the only way to do it.
Wrap 2 jackets around the process. Both have the same effect as
they would if they were the only jackets in the stack. This is
a really hard trick, but coat does it.
Any chroot can ruin your day.
There is no jail(8) access for FreeBSD platforms (yet).
K S Braunsdorf, from the Non-Player Character Guild
op at-not-a-spammer ksb dot npcguild.org
sh(1), op(1l), sudo(1), coat(7l), envauth(7l), manifest(7l), proxy-
agent(7l), sheval(7l), signed(7l), stamp(7l), stampctl(8l),
timebox(7l), wrope(7l), xdisplay(7l)
API COMMANDS |