Skip to content

Permissions and Secrets

Jon Seager edited this page Feb 19, 2024 · 12 revisions

ⓘ This page describes how the permissions should be set on completely automated snaps. Due to our large backlog of snaps, not all snaps are completely automated yet, so not all snaps use these permission settings. If you are setting up automation for a snap, please also configure permissions as stated here, or ask a Snapcraft Administrator to setup the permissions.

With advanced automation and bots setup, it's important that the repository and store permissions are set correctly. Our snaps have a large userbase, so we have a large responsibility to keep everything protected. Employing least-privileges principles is an important part of that.

General idea

  • Snapcrafter Administrators have full privileges, both on GitHub and in the Snap store.
  • All other contributors should have the least amount of privileges possible to do their job efficiently and unimpeded.
  • snapcrafters-bot is allowed to bypass branch protection rules.

This means that, once automation is setup so that regular snapcrafters can direct everything from GitHub, only the administrators need access to the store.

[GitHub] Collaborators and teams

Add the following users and teams to the repository. All other users and teams should be removed.

User/Team Permission
administrators Admin
reviewers Write
snapcrafters-bot Write

[GitHub] Automated Setup

The process below for creating secrets and environments is somewhat arduous and prone to error. To automate this process, we created tokenator. Tokenator takes care of creating branch protection rules, environments and populating those environments with secrets.

[Github] Renewing tokens with Tokenator

In order to just renew tokens without making any changes to configuration, checkout the tokenator repository, ensure that the dotenv file is setup as per the README file, then run:

go run .

Tokenator will then run through each repository issuing new credentials. To renew for a single repository (sublime-text in the example below), try:

go run . -r sublime-text

[Github] Adding credentials to a repo for the first time

To add credentials to a new repo for the first time, again begin by checking out tokenator. Next adjust the tokenator.yaml file, adding the details of the repository.

Once complete, issue credentials like so:

go run . -r <repo-name>

[Github] Manual Setup

[GitHub] Branches (Branch protection rules)

Create a branch protection rule applying to all branches.

image

Set the following permissions on that rule.

  • ☑️ Require a pull request before mergins
    • ☑️ Require approvals
    • ☑️ Dismiss stale pull request approvals when new commits are pushed
    • ☑️ Allow specified actors to bypass required pull requests
      • snapcrafters-bot
  • ☑️ Restrict who can push to matchin branches
    • ☑️ Restrict pushed that create matching branches
    • People, teams or apps with push access
      • snapcrafters-bot

The reasoning behind it. Creating new branches is a common way to steal repository secrets and gain unauthorized access to a repository. We locked this down specifically to prevent such attacks. We also use an Environment locked to the candidate branch as a second layer of defense against stealing these secrets.

Permissions and security for GitHub actions and Secrets is quite difficult to get right, and it's made worse by

  • having a bot that is permitted to push directly to the repo without any checks
  • having a large and diverse group of people with write access to all repos

These permissions are hard to get right, and GitHub actions has already had a number of vulnerabilities in its lifetime. We want to avoid such a vulnerability giving people access to our large userbase.

[GitHub] Environments - Manual Setup

The secrets used by the GitHub actions are stored in an Environment, in order to add a second layer of protection.

Each repository has one environment: "Candidate Branch". This environment is locked to the candidate branch.

image

It has four secrets:

  • SNAPCRAFTERS_BOT_COMMIT is a GitHub token for snapcrafters-bot that has write access to only that single snap's repository and the ci-screenshots repository. You create it on GitHub in Settings > Developer settings > Fine-grained Personal Access Tokens.

    • Name: snapcrafters/<repo> commit
    • Resource owner: snapcrafters
    • Repository access: "Only select repositories" > <repo> and ci-screenshots
    • Permissions: Contents > "Access: Read and write".
  • LP_BUILD_SECRET is a Launchpad token that can be used to build snaps on Launchpad. You generate this by running snapcraft remote-build on your local machine, login using the snapcrafters-bot account, and copy the token with the following command.

    cat ~/.local/share/snapcraft/provider/launchpad/credentials
  • SNAP_STORE_CANDIDATE is a Snap Store token that is only allowed to push a snap to the candidate channel. You can generate it with the following command.

    SNAP_NAME=mattermost-desktop
    snapcraft export-login --snaps=${SNAP_NAME} \
       --acls package_access,package_push,package_update,package_release \
       --channels candidate \
       --expires 2024-12-07 \
       SNAP_STORE_CANDIDATE
  • SNAP_STORE_STABLE is a Snap Store token that is only allowed to promote a snap from candidate to the stable channel. You can generate it with the following command.

    SNAP_NAME=mattermost-desktop
    snapcraft export-login --snaps=${SNAP_NAME} \
      --acls package_access,package_release \
      --channels stable \
      --expires 2024-12-07 \
      SNAP_STORE_STABLE

[Snap Store]

Each snap should only have the Snapcraft Administrators listed as Collaborators. Please contact the Administrators to get the correct email addresses.

Additionally, the Snap Store should have the "Update metadata on release" flag set, so that the metadata in snapcraft.yaml will be the metadata in the Snap Store.

image