Setting protections with p4 protect
p4 protect form contains a single form field
Protections: that consists of multiple lines. Each
Protections: contains subfields, and the table looks
Example A sample protections table
Protections: read user emily * //depot/elm_proj/... write group devgrp * //... write user * 192.168.41.0/24 -//... write user * [2001:db8:1:2::]/64 -//... write user joe * -//... write user lisag * -//depot/... write user lisag * //depot/doc/... super user edk * //...
(The five fields might not line up vertically on your screen; they are aligned here for readability.)
Proxy and protections
To apply the IP address of a
user’s workstation against the protections table, prepend the string
proxy- to the workstation’s IP address.
Before you prepend the string
proxy- to the
workstation’s IP address, make sure that a broker or proxy is in place.
For instance, consider an organization with a remote development site
with workstations on a subnet of
organization also has a central office where local development takes
place; the central office exists on the
10.0.0.0/8 subnet. A
service resides in the
10.0.0.0/8 subnet, and a
resides in the
192.168.10.0/24 subnet. Users at the remote
site belong to the group
remotedev, and occasionally visit
the central office. Each subnet also has a corresponding set of IPv6
To ensure that members of the
remotedev group use the proxy
while working at the remote site, but do not use the proxy when visiting
the local site, add the following lines to your protections table:
list group remotedev 192.168.10.0/24 -//... list group remotedev [2001:db8:16:81::]/48 -//... write group remotedev proxy-192.168.10.0/24 //... write group remotedev proxy-[2001:db8:16:81::]/48 //... list group remotedev proxy-10.0.0.0/8 -//... list group remotedev proxy-[2001:db8:1008::]/32 -//... write group remotedev 10.0.0.0/8 //... write group remotedev [2001:db8:1008::]/32 //...
The first line denies
list access to all users in the
remotedev group if they attempt to access
without using the proxy from their workstations in the
192.168.10.0/24 subnet. The second line denies access in
identical fashion when access is attempted from the IPV6
The third line grants
write access to all users in the
remotedev group if they are using a
server and are working from the
Users of workstations at the remote site must use the proxy. (The proxy
server itself does not have to be in this subnet, for example, it could
192.168.20.0.) The fourth line grants access in
identical fashion when access is attempted from the IPV6
Similarly, the fifth and sixth lines deny
list access to
remotedev users when they attempt to use the proxy from
workstations on the central office’s subnets (
[2001:db8:1008::]/32). The seventh and eighth lines grant
write access to
remotedev users who access the
directly from workstations on the central office’s subnets. When
visiting the local site, users from the
remotedev group must
Helix server directly.
service evaluates protections table entries, the
dm.proxy.protects configurable is also evaluated.
dm.proxy.protects defaults to
1, which causes
proxy- prefix to be prepended to all client host
addresses that connect via an intermediary (proxy, broker, replica, or
edge server), indicating that the connection is not direct.
0 removes the
proxy- prefix and allows you to write a single set of
protection entries that apply both to directly-connected clients as well
as to those that connect via an intermediary. This is more convenient but
less secure if it matters that a connection is made using an
intermediary. If you use this setting, all intermediaries must be at
release 2012.1 or higher.
Each line specifies values for the subfields:
Which access level (
In general, one typically grants an access level to a user or group, after which, if finer-grained control is required, one or more specific rights may then be denied.
Does this protection apply to a
The user or group whose protection level is being defined. This
field can contain the
The TCP/IP address of the host being granted access. This must
be provided as the numeric address of either one specific host
The host field can also contain the
You cannot combine the
For more about controlling access to a Helix server via the Helix Proxy, see Helix Proxy.
A file specification representing the files in the depot on which permissions are being granted. Helix server wildcards can be used in the specification.
If a depot is excluded, the user denied access will no longer
see the depot in the output of
The access level is described by the first value on each line. The permission levels and access rights are described in the following table:
Permission is granted to run
commands that display file metadata, such as
Grants permission to read files from the depot into the client
workspace, and gives permission to open and edit those files.
This permission does not permit the user to write the files back
to the depot. The
Permission is granted to run those commands that edit, delete,
or add files. The
This permission allows use of all
If this right is denied, users cannot submit open files.
If this right is denied, users may not use files as a source for
Provides list and read access, plus use of the
Allows access to the
administrators; grants permission to run
commands that affect metadata, but not server operation. Provides
superusers; grants permission to run all
command is associated with a particular minimum access level. For
example, to run
read access on that file. For a full list
of the minimum access levels required to run each
How protections are implemented.
The specific rights of
=branch can be used to override the
automatic inclusion of lower access levels. This makes it possible to
deny individual rights without having to then re-grant lesser rights.
For example, if you want administrators to have the ability to run administrative commands, but to deny them the ability to make changes in certain parts of the depot, you could set up a permissions table as follows:
admin user joe * //... =write user joe * -//depot/build/... =open user joe * -//depot/build/...
In this example, user
joe can perform administrative
functions, and this permission applies to all depots in the system.
admin permission level also implies the granting
of all lower access levels,
joe can also write, open, read
and list files anywhere in the system, including
//depot/build/. To protect the build area, the
=open exclusionary lines are added
to the table. User
joe is prevented from opening any files
for edit in the build area. He is also prevented from submitting any
changes in this area he might already have open. He can continue to create
and modify files, but only if those files are outside of the protected
Stream spec permissions
Prior to release 2020.1, there were no protections modes specific to stream specs. The permissions for listing, reading, and editing stream specs were inferred from the corresponding filespec protections as follows:
listpermission in a depot granted the ability to run p4 streams to list streams in that depot
writepermission on a file spec granted the ability to edit and save any stream spec whose stream root matches that file spec
The 2020.1 release added protections modes that are specific to stream specs. By default, these permissions can exist in the protection table, but will not be used until the dm.protects.streamspec configurable has been set to
1. If the
dm.protects.streamspec configurable is set to
1 and any stream spec permissions exist in the protection table, the pre-2020.1 permissions no longer apply and all users who are not admin or super require explicit stream spec permissions.
If you want to implement the legacy permissions with the stream spec permissions:
- Create a user group containing all users who require
readstreamspec group readgroup * //...
- Create another user group containing all users who require
writestreamspec group writegroup * //...
||The user can display a stream spec with
||If this right is denied, users cannot execute
||This gives the user permission to revert, resolve, shelve, or open for edit a stream spec.|
||If this right is denied, users cannot revert, resolve, shelve, or open for edit a stream spec.|
||The user can submit or modify a stream spec.|
||If this right is denied, users cannot submit or modify a stream spec.|
If any streamspec permissions exist for any user:
- users without explicit streamspec permissions have no access to stream specs
listcontinues to provide p4 streams access
If no streamspec permission exists for any user:
p4 streamsaccess for stream spec paths.
openor higher permssion for a user anywhere grants stream spec
writepermissions to that user for all stream specs.
p4 protect is invoked, every user has
superuser privileges. When
p4 protect is first run,
two permissions are set by default. The default protections table looks
write user * * //... super user edk * //...
This indicates that
write access is granted to all users,
on all hosts, to all files. Additionally, the user who first invoked
p4 protect (in this case,
granted superuser privileges.
Which users should receive which permissions?
The simplest method of granting permissions is to give
write permission to all users who don’t need to manage the
super access to those who do, but there are times
when this simple solution isn’t sufficient.
Read access to particular files should be granted to users
who never need to edit those files. For example, an engineer might have
write permission for source files, but have only
read access to the documentation, and managers not working
with code might be granted
read access to all files.
open access enables local editing of files, but
does not permit these files to be written to the depot,
access is granted only in unusual circumstances. You might choose
open access over
write access when users are
testing their changes locally but when these changes should not be seen
by other users. For instance, bug testers might need to change code in
order to test theories as to why particular bugs occur, but these changes
are not to be written to the depot. Perhaps a codeline has been frozen,
and local changes are to be submitted to the depot only after careful
review by the development team. In these cases,
is granted until the code changes have been approved, after which time
the protection level is upgraded to
write and the changes
open access is also useful with shelves. Using
open is enough to shelve changes but not submit them and can
be useful for code reviews.
Interpreting multiple permission lines
The access rights granted to any user are defined by the union of mappings in the protection lines that match her user name and client IP address. (This behavior is slightly different when exclusionary protections are provided and is described in the next section.)
lisag, is using a workstation with the IP
220.127.116.11. The protections file reads as
read user * 18.104.22.168 //... write user lisag 22.214.171.124 //depot/elm_proj/doc/... read user lisag * //... super user edk * //...
The union of the first three permissions applies to Lisa. Her username
lisag, and she’s currently using a client workspace on
the host specified in lines 1 and 2. Thus, she can write files located
in the depot’s
elm_proj/doc subdirectory but can only read
other files. Lisa tries the following:
p4 edit depot/elm_proj/doc/elm-help.1,
and is successful.
p4 edit //depot/elm_proj/READ.ME, and is
told that she doesn’t have the proper permission. She is trying to
write to a file to which has only
read access. She types
p4 sync depot/elm_proj/READ.ME, and this command
succeeds, because only
read access is needed, and this is
granted to her on line 1.
Lisa later switches to another machine with IP address
126.96.36.199. She types
//depot/elm_proj/doc/elm-help.1, and the command fails because on this host, only the third permission applies to her,
and she only has read privileges.
It is possible to delegate management of parts of the protections table
to non-super users or groups by creating an entry with the mode
owner. These entries must have a unique path, without
wildcards, except for a trailing ellipsis (
super or that have been granted
owner for a path can run the
command specifying the granted path as an argument, accessing the
sub-protections table for that path.
The server appends any entries in this table to the effective protections table directly below the owner entry; if an owner entry is removed, so are any entries in the sub-protections table for that path. Neither owner nor super entries can be added to a sub-protections table, and any other entries' paths must be within the scope of the sub-protections table’s path.
If a path argument is specified, and an owner entry with the same path exists, the sub-protections table for that path will be accessed instead of the main protections table.
Suppose super user Bruno issues the following commands:
# Create a user called Sally $ p4 user -f sally # Create a depot called stats $ p4 depot stats # Edit the protections table $ p4 protect
The last command opens the protections table in an editor. Let’s suppose the protections table contains the following lines:
Protections: write user * * //... super user bruno * //...
Suppose Bruno wants to delegate control of the sub-protections table for
//stats/dev/… to Sally. He edits the protections
table to append the necessary line to the protections table, which now
looks like this:
Protections: write user * * //... super user bruno * //... owner user sally * //stats/dev/...
A user can be denied access to particular files by prefacing the fifth
field in a permission line with a minus sign (
-). This is
useful for giving most users access to a particular set of files, while
denying access to the same files to only a few users.
To use exclusionary mappings properly, it is necessary to understand some of their peculiarities:
- When an exclusionary protection is included in the protections table, the order of the protections is relevant: the exclusionary protection is used to remove any matching protections above it in the table.
- No matter what access level is provided in an exclusionary protection, all access levels for the matching files and IP addresses are denied. The access levels provided in exclusionary protections are irrelevant. See How protections are implemented for a more detailed explanation.
- Without exclusionary mappings, the order of items in the protections table is not important.
An administrator has used
p4 protect to set up
protections as follows:
write user * * //... read user emily * //depot/elm_proj/... super user joe * -//... list user lisag * -//... write user lisag * //depot/elm_proj/doc/...
The first permission looks like it grants write access to all users to all files in all depots, but this is overruled by later exclusionary protections for certain users.
The third permission denies Joe permission to access any file from any host. No subsequent lines grant Joe any further permissions; thus, Joe has been effectively denied any file access.
The fourth permission denies Lisa all access to all files on all
hosts, but the fifth permission gives her back
access on all files within a specific directory. If the fourth and
fifth lines were switched, Lisa would be unable to run any
Displaying protections for a user, group, or path.
p4 protects command to display the lines
from the protections table that apply to a user, group, or set of
With no options,
p4 protects displays the lines in
the protections table that apply to the current user. If a
file argument is provided, only those lines in the
protection table that apply to the named files are displayed. Using the
-m flag displays a one-word summary of the maximum
applicable access level, ignoring exclusionary mappings.
superusers can use
p4 protects -a to see all lines
for all users, or
p4 protects -u
host flags to see lines for a specific user,
group, or host IP address.
-s option to display protection information from a
protect table referenced by the file revision specified with the
spec argument. For example, the following command
returns information about the user sam in the third revision of the
C:\> p4 -u super protects -s //spec/protect.p4s#3 -u sam write user* * //...
This is useful when users lose access privileges at a given point in time and you want to check what changes were made to the protection table just before that date.
To use this option, you must define a spec depot for protect forms;
this automatically saves revisions to the protect specification every
time you edit the protection table. See the description of the
p4 depot command in the
Helix Core P4 Command Reference
for information on how to create a spec depot.