Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Init

Prerequisites

sesam relies a lot on git for some functionality. You can either use an existing repository to manage your secrets in or you can create a whole new one. If you use an existing repository we recommend an empty sub-directory to manage your secret files in. The .sesam directory does not need to be on the same level as the .git folder.

Creating a new repository

In the folder you've selected run:

$ sesam init --identity ~/.ssh/whatever-key-you-want

This command will do the following:

  • Create a folder .sesam/ in the current directory.
  • Create a default config file in sesam.yml. It is a declarative config describing the state we want in our repo.
  • Create a .gitignore that ignores everything but .sesam/ and .sesam.yml. This is to protect revealed secret so they never get accidentally added to git.
  • Create .gitattributes that tells git what to do with the encrypted files.
  • It will also do a couple other git operations that are described here.
  • It will also create a first secret: README.sesam. Read it for a very condensed version of this tutorial.
  • We will guess the initial user's name from your git config. If you want a different name then use the --user parameter or rename later.
  • The initial user will automatically be an admin user. sesam has the concept of users with different access levels.
  • Every user needs an identity - a cryptographic way to prove he is this specific user. In the example above we used an ssh key.

Note

Hi! In those notes we're trying to give you some background information on why things are the way they are. You probably won't loose too much required info if you don't read those boxes, but we recommend to do so. You may remember that using git got easier when you understood how it works under the hood? Anyway, let's continue:

The --idenity option has to be passed to most sesam commands. Typing this out is tedious, but luckily we support specifying almost all command line flags as environment variable. If you place this in your .bashrc (or whatever you use), then you never need to specify the identity path again:

export SESAM_IDENTITY=~/.ssh/whatever-key-you-want

The rest of this guide assumes that you've exported an environment variable.

Identities

An identity is just a fancy name for a private key that is attached to a specific user. sesam supports the following keys as identity:

  • SSH Keys (RSA and ed25519, may be passphrase protected)
  • Age Keys (generated by age-keygen, also maybe be passphrase protected)
  • Age plugins

If you want to use several of them you can also pass --identity (or short -i) several times. Then sesam will use all of them for encryption and decryption.

Warning

You are responsible for storing your identity in a safe place. You should not store it as part of the sesam repository.

If you want to know as what user you identify as, just type:

$ sesam id
bob

With the --json option you also get the public keys you are using:

$ sesam id --json
{
  "name": "bob",
  "groups": [
    "admin"
  ],
  "sign_pub_key": [
    "7QEg5yp1mHH3sy/3AOhBIaNNbZPh7cVlifod+04wzutudko="
  ],
  "recipients": [
    {
      "key": "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIN5VzGK/HxjYdIjBnRi6Nq7/0ydsKpX3uk1gu/ywUDJj",
      "source": "manual"
    }
  ]
}

Info

We try to be very script-friendly - you will find that most commands support a --json switch that can then be piped to helpers like jq easily.

Passphrase protected identities

Both ssh and age support encrypting keys at rest with a passphrase. To unlock them before use we have to ask the user what the passphrase is. This can be done either:

  1. By asking the user directly on terminal when we detect such a key.
  2. By reading the passphrase from the OS keyring (e.g. where it was stored from last time)
  3. By using a askpass program like ssh-askpass, systemd-askpass or similar that may ask the user via alternative UI.

For option 3 you need a compatible program installed and have set any of those variables to the name of the program, so sesam knows what to call:

  • SESAM_ASKPASS (or --askpass global option)
  • GIT_ASKPASS - used in git context.
  • SSH_ASKPASS - used in git and ssh context.

This is especially important if you want to use the git integration from an IDE - here sesam won't have a terminal it can use. We also honor the related *_ASKPASS_REQUIRED variable (i.e. SESAM_ASKPASS_REQUIRED, GIT_ASKPASS_REQUIRED, SSH_ASKPASS_REQUIRED) which can be set to the one those values:

  • never: Never ask via askpass. Disables it effectively.
  • prefer: If possible, use the graphical interface.
  • force: Use it even if have a terminal available that we could ask from.

You don't need to set it though, we will use a sensible default.

Your desktop environment might already set these environment variables. If it does not, install a program like ksshaskpass and set SESAM_ASKPASS=ksshaskpass.

Recipients

Every user of sesam has at least one recipient. Think of it as the public part to the identity. While only you possess your identity, everyone has access to all recipients. With recipients we can control which secrets are accessible for which users: A secret that should be accessible by Alice and Bob simply gets encrypted with the set of recipients of both users.

Shell completion

We have support for shell completion for most popular shells thanks to the urfave/cli package.

# Choose your shell:
source <(../sesam completion bash)
source <(../sesam completion zsh)
source <(../sesam completion fish)

This will enable it only for the current shell. Put it in your shell config (.bashrc, .zshrc, ...) to make it permanent. Some day this might be pre-installed for you. When this day comes we document it here.

git push --force and sesam

The tamper detection of sesam assumes linear, append-only history. The audit log is verified by walking git history and checking that the log at each commit is a strict prefix of the log at the next - it may grow, but never shrink or change underneath you. The init UUID pinned in the first commit anchors that chain.

A force-push breaks the assumption. By rewriting history it can drop or replace commits, so a truncated or substituted audit log can be made to look like the legitimate tip. `sesam`` can still detect this if it has an older copy to compare against (a local clone, a CI checkout, another collaborator's repo), but it cannot detect it from the rewritten remote alone.

Warning

Treat force-push as out of scope for sesam's guarantees. Disable it at the forge for any branch that carries a .sesam directory:

  • GitHub/Gitea: enable branch protection and forbid force-push.
  • GitLab: mark the branch protected with "Allowed to force push" off.
  • Self-hosted: receive.denyNonFastForwards = true, or a pre-receive hook.

If a force-push does happen, do not trust the remote state. Compare against a known-good clone and run sesam verify --all before relying on any secret.

The linear-history requirement is usually the better default anyway, and most forges make it a one-click setting.

If the force pushed did only affect files out of sesam, then we should be fine.

- -force-with-lease makes no difference here by the way.

Calling the doctor

If you are unsure if there's something wrong with your installation of sesam, then run this:

$ sesam doctor

This will check the installation and print any issue along with tips on how to fix them.

Uninstalling sesam

If you want to get rid of sesam (☹) then you can just run sesam uninstall. This will by default remove all git integration that was previously installed (i.e. remove our .gitignore changes, .gitattributes and .git/config).

If you also want to get rid of all the sesam.yml files and .sesam/ directory then run sesam uninstall --all. That will ask you though.

Built unknown • commit: