Setting protections with p4 protect

The p4 protect form contains a single form field called Protections: that consists of multiple lines. Each line in Protections: contains subfields, and the table looks like this:

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 Helix Proxy user’s workstation against the protections table, prepend the string proxy- to the workstation’s IP address.

Important

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 192.168.10.0/24. The organization also has a central office where local development takes place; the central office exists on the 10.0.0.0/8 subnet. A Perforce service resides in the 10.0.0.0/8 subnet, and a Helix Proxy 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 addresses.

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 Helix Server 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 [2001:db8:16:81::]/48 subnet.

The third line grants write access to all users in the remotedev group if they are using a Helix Proxy server and are working from the 192.168.10.0/24 subnet. 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 be at 192.168.20.0.) The fourth line grants access in identical fashion when access is attempted from the IPV6 [2001:db8:16:81::]/48 subnet.

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 (10.0.0.0/8 and [2001:db8:1008::]/32). The seventh and eighth lines grant write access to remotedev users who access the Helix Server directly from workstations on the central office’s subnets. When visiting the local site, users from the remotedev group must access the Helix Server directly.

When the Perforce service evaluates protections table entries, the dm.proxy.protects configurable is also evaluated.

dm.proxy.protects defaults to 1, which causes the 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.

Setting dm.proxy.protects to 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.

Permission subfields

Each line specifies values for the subfields:

Subfield Meaning

Access Level

Which access level (list, read, open, write, review, owner, admin, or super) or specific right (=read, =open, =write, or =branch) is being granted or denied.

  • Each permission level includes all the permissions above it (except for review).
  • Each permission right (denoted by an =) only includes the specific right and not all of the lesser rights.

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.

User/Group

Does this protection apply to a user or a group?

Name

The user or group whose protection level is being defined. This field can contain the * wildcard. A * by itself grants this protection to everyone, *e grants this protection to every user (or group) whose username ends with an e.

Host

The TCP/IP address of the host being granted access. This must be provided as the numeric address of either one specific host (for instance, 192.168.41.2 or [2001:db8:195:1:2::1234]) or a subnet expressed in CIDR notation.

The host field can also contain the * wildcard. A * by itself means that this protection is being granted for all hosts. The wildcard can be used as in any string, so 192.168.41.* is equivalent to 192.168.41.0/24.

You cannot combine the * wildcard with CIDR notation, except at the start of a line when controlling proxy matching. If you are using IPv6 with the * wildcard, you must enclose the address with square brackets. [2001:db8:1:2:*] is equivalent to [2001:db8:1:2::]/64. Best practice is to use CIDR notation, surround IPv6 addresses with brackets, and to avoid the * wildcard.

For more about controlling access to a Helix Server via the Helix Proxy, see Helix Proxy.

Files

A file specification representing the files in the depot on which permissions are being granted. Helix Server wildcards can be used in the specification.

"//..." means all files in all depots.

If a depot is excluded, the user denied access will no longer see the depot in the output of p4 depots. Nor will the depot show up, for this user, in the default branch, client, and label views.

Access levels

The access level is described by the first value on each line. The permission levels and access rights are described in the following table:

Level Meaning

list

Permission is granted to run Helix Server commands that display file metadata, such as p4 filelog. No permission is granted to view or change the contents of the files.

read

The user can run those Helix Server commands that are needed to read files, such as p4 client and p4 sync. The read permission includes list access.

=read

If this right is denied, users cannot use p4 print, p4 diff, or p4 sync on files.

open

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 open level is similar to write, except that with open permission, users are not permitted to run p4 submit or p4 lock.

The open permission includes read and list access.

=open

If this right is denied, users cannot open files with p4 add, p4 edit, p4 delete, or p4 integrate.

write

Permission is granted to run those commands that edit, delete, or add files. The write permission includes read, list, and open access.

This permission allows use of all Helix Server commands except protect, depot, obliterate, and verify.

=write

If this right is denied, users cannot submit open files.

=branch

If this right is denied, users may not use files as a source for p4 integrate.

review

Provides list and read access, plus use of the p4 review command. This is a special permission granted to review scripts.

owner

Allows access to the p4 protect command to the specified user or group, for the specified path. See Delegate management of parts of the protections table for details.

admin

For Helix Core Server administrators. Grants permission to run Helix Core Server commands that affect metadata, but not server operation. Provides write and review access plus the added ability to override other users' branch mappings, client specifications, jobs, labels, and change descriptions, as well as to update the typemap table, verify files, obliterate files, and customize job specifications.

super

For Helix Core Server superusers. Grants permission to run all Helix Core Server commands. Provides write, review, and admin access, plus the added ability to create depots and triggers, edit protections, edit user groups, delete users, reset passwords, and shut down the server.

Each Helix Server command is associated with a particular minimum access level. For example, to run p4 sync or p4 print on a particular file, the user must have been granted at least read access on that file. For a full list of the minimum access levels required to run each Helix Server command, see How protections are implemented.

The specific rights of =read, =open, =write, and =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. Because the 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 =write and =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 //depot/build/... area.

Stream spec permissions

readstreamspec The user can display a stream spec with p4 stream -o
=readstreamspec If this right is denied, users cannot execute p4 stream -o
openstreamspec This gives the user permission to revert, resolve, shelve, or open for edit a stream spec.
=openstreamspec If this right is denied, users cannot revert, resolve, shelve, or open for edit a stream spec.
writestreamspec The user can submit or modify a stream spec.
=writestreamspec If this right is denied, users cannot submit or modify a stream spec.
Note

If any streamspec permissions exist for any user:

  • users without explicit streamspec permissions have no access to stream specs
  • list continues to provide p4 streams access

If no streamspec permission exists for any user:

  • Any open or higher permssion for a user anywhere grants stream spec edit and write permissions to that user for all stream specs.

Default protections

Before 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 like this:

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, edk) is 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 Helix Server system and 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.

Because open access enables local editing of files, but does not permit these files to be written to the depot, open 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, open access is granted until the code changes have been approved, after which time the protection level is upgraded to write and the changes submitted. 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.

Tip

To see which permission is required for a given p4 command, see Access levels required by Helix Server commands.

To learn about the standard users, operator users, and service users, see Types of users in Helix Core Command-Line (P4) Reference.

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.)

Example    

Lisa, whose Helix Server username is lisag, is using a workstation with the IP address 195.42.39.17. The protections file reads as follows:

read      user    *        195.42.39.17     //...
write     user    lisag    195.42.39.17     //depot/elm_proj/doc/...
read      user    lisag    *                //...
super     user    edk      *                //...

The union of the first three permissions applies to Lisa. Her username is 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:

She types p4 edit depot/elm_proj/doc/elm-help.1, and is successful.

She types 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 195.42.39.13. She types p4 edit //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.

Delegate management of parts of the protections table

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 (…​).

Users with super or that have been granted owner for a path can run the p4 protect 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 the path //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/...

Exclusionary protections

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.

Example    

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 write access on all files within a specific directory. If the fourth and fifth lines were switched, Lisa would be unable to run any Helix Server command.

Displaying protections for a user, group, or path.

Use the p4 protects command to display the lines from the protections table that apply to a user, group, or set of files.

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.

Helix Server superusers can use p4 protects -a to see all lines for all users, or p4 protects -u user, -g group, or -h host flags to see lines for a specific user, group, or host IP address.

Use the -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 protections table:

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.

Note

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 Command-Line (P4) Reference for information on how to create a spec depot.