Skip to content

Latest commit

 

History

History
188 lines (144 loc) · 6.45 KB

server.md

File metadata and controls

188 lines (144 loc) · 6.45 KB

Running a setec server

The server subcommand of the setec command line tool implements an HTTP server for the setec API. The server uses tsnet to join a tailnet of your choosing.

The CLI is written in Go. To install the command-line tool, either:

go install github.com/tailscale/setec/cmd/setec@latest

or clone this repository and build it from source:

git clone https://github.com/tailscale/setec
cd setec
go build ./cmd/setec

The rest of this document assumes you have the setec command-line tool somewhere in your $PATH.

Basic Setup

Run setec help server for a summary of command-line options. To run the server you must provide at least a --hostname for the service to use, and a --state-dir path where it will store its persistent state.

The first time you run the server you must also provide a Tailscale auth key via the TS_AUTHKEY environment variable, so that the server can join your tailnet. You can omit this on subsequent invocations -- the server will use the contents of the specified --state-dir to reconnect to the same tailnet.

Key Management

The server stores secrets in an encrypted file in the state directory. When the server starts, it requires an access key to unlock the database.

In production, the server fetches an access key from an AWS KMS secret, whose ARN is specified via the --kms-key-name flag. As of 05-May-2024, AWS KMS is the only supported production access key store; we may add others in the future.

This mode also requires access to the AWS APIs: If you are running the server in AWS (e.g., an EC2 VM), you would typically grant access to the key via an IAM role on the VM. Alternatively, you can plumb in credentials via environment variables, for example using aws-vault or similar.

For development and testing purposes, the server also supports a --dev flag, which runs using a "dummy" static access key. This mode is not secure for production use, but is useful for testing and debugging integrations locally.

Usage Examples

Note

In the examples below, you must provide a real value for TS_AUTHKEY obtained from your tailnet's admin panel. The value shown below is a fake key that will not work.

  1. To run a setec server in development mode under the hostname setec-dev:

    TS_AUTHKEY=tskey-auth-kf4k3k3y4testCNTRL-ZmFrZSBrZXkgZm9yIHRlc3Q setec server \
      --hostname=setec-dev \
      --state-dir=$HOME/setec-dev \
      --dev
  2. To run a setec server in production mode under the hostname secrets:

    TS_AUTHKEY=tskey-auth-kf4k3k3y4testCNTRL-ZmFrZSBrZXkgZm9yIHRlc3Q setec server \
      --hostname=secrets \
      --state-dir=$HOME/setec-state \
      --kms-key-name=arn:aws:kms:us-east-1:123456789012:key/b8074b63-13c0-4345-a9d8-e236267d2af1

    Note that the KMS key name shown here is a fake one, you must replace it with a real one from your own account. You may also need to set up other AWS environment variables (e.g. AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY). For example, using aws-vault it might look like this:

    TS_AUTHKEY=tskey-auth-kf4k3k3y4testCNTRL-ZmFrZSBrZXkgZm9yIHRlc3Q aws-vault exec myaccount -- \
      setec -server \
        --hostname=setec-dev \
        --state-dir=$HOME/setec-dev \
        --kms-key-name=arn:aws:kms:us-east-1:123456789012:key/b8074b63-13c0-4345-a9d8-e236267d2af1

Once you have run the server, you can grant access to it via your tailnet ACL. For example, if we assume your server's Tailscale address is 100.64.5.6, the following ACL grants would give the administrators of your tailnet full access to all secrets in your service via the API:

    "grants": [
        {
            "ip":  ["*"],
            "src": ["autogroup:admin"],
            "dst": ["100.64.5.6"],

            // Alternatively, assign your node a tag, e.g., tag:secrets, and
            // use the tag as the dst instead.
        },
        {
            "src": ["autogroup:admin"],
            "dst": ["100.64.5.6"],
            "app": {
                "tailscale.com/cap/secrets": [
                    {
                        "action": ["get", "info", "put", "activate", "delete"],
                        "secret": ["*"],
                    },
                ],
            },
        },
    ],

In practice, you will want to scope these permissions more narrowly, e.g., granting "get" permission for individual secrets only to the servers that need those values.

To test that this is working properly on a new server, try:

echo -n "hello, world" | setec -s https://setec-dev.example.ts.net put dev/hello-world

(replacing example.ts.net with your tailnet name). This should print:

Read 12 bytes from stdin
Secret saved as "dev/hello-world", version 1

Assuming that works, you should then be able to run:

setec -s https://setec-dev.example.ts.net list

which should give you output like:

NAME            ACTIVE VERSIONS
dev/hello-world 1      1

Note that the first time you call the server, it may take thirty seconds or longer as the server will need to obtain a TLS certificate from LetsEncrypt. Subsequent calls will run faster.

Other Considerations

Backups

When running setec in production, you will generally want to keep backups of your secrets data. The setec server command has basic support for automatic backups to S3 via the optional --backup-bucket and --backup-bucket-region flags. When these are set, the server automatically backs up the database to a timestamped object in S3 up to once per minute, if its contents have changed since the last backup.

The uploaded backups are fully encrypted.

Audit Logs

While running, the server appends a basic audit log of all secret accesses to a file called audit.log in its state directory. These logs can be used to check which secrets were accessed when, by which users and/or services on the tailnet. For now (as of 05-May-2024), the audit logs are stored only in the server's state directory.