Skip to main content

Working in CLI

Overview

Using the console client tuna, you can get secrets, automatically configure the current environment, or pass configuration to the env of the required application.

To get secrets through the tuna console application or API, you need a user API key or Configuration Service Key. For local development, it's more convenient to use global user API keys, but for CI/CD, Production, and other shared environments, we strongly recommend using Configuration Service Keys.

Why is tuna secrets better than direnv for local development?

direnv is a great utility for local configuration, but it still makes you monitor the local .env file, and if new variables appeared in Production, you may not know about it immediately and spend hours on pointless debugging. In tuna secrets, there is automatic secret synchronization, which greatly simplifies this process.

Why is tuna secrets better than Gitlab/Github/Bitbucket Variables?

Actually, the reason here is the same as with direnv. For example, you have a special project designed for building and publishing an application using goreleaser and it may require many keys and tokens for different external integrations, while for different environments, and using Gitlab/Github/Bitbucket Variables for this is inconvenient, and it's even more inconvenient to monitor this, plus the complexity in access control. In tuna secrets, access to environments is regulated by RBAC, and you can precisely distribute access only to the necessary people/robots/scripts. And by updating a secret or adding a new one, it will immediately start working in CI.

Authorization

To access secrets, you need a Service Key of a specific configuration or a user API key. It can be passed through the --api-key flag, the TUNA_API_KEY environment variable, or saved to the config file with tuna config save-api-key <your-key>

Download

To get secrets, you need to run the command:

tuna secrets download

Through additional flags or environment variables you can define settings like project and configuration.

Passing project and configuration

The --project and --config flags take the name (alias) of the project and configuration as input. By default, the configuration will be saved to the tuna.json file in the current directory.

$ tuna secrets download --project api-php --config stage
INFO[13:57:46] Downloaded secrets to tuna.json

$ cat tuna.json
{
"API_DB": "postgres://postgres:postgres@localhost:5432/postgres",
"API_TOKEN": "PwZayIp9NpNntNYd2jkAAQgViM6dXdIm"
}

Passing format

You can specify the format you need for the file: json, yaml, or env.

$ tuna secrets download --project api-php --config stage --format json
INFO[14:01:50] Downloaded secrets to tuna.json

$ cat tuna.json
{
"API_DB": "postgres://postgres:postgres@localhost:5432/postgres",
"API_TOKEN": "PwZayIp9NpNntNYd2jkAAQgViM6dXdIm"
}

Custom file

You can pass a path in the command to define your own file.

$ tuna secrets download --project api-php --config stage foo-bar.json
INFO[14:11:57] Downloaded secrets to foo-bar.json

Output to stdout

The --no-file flag disables writing to a file and prints the configuration to standard output.

$ tuna secrets download --project api-php --config stage --no-file --format env
API_TOKEN="PwZayIp9NpNntNYd2jkAAQgViM6dXdIm"
API_DB="postgres://postgres:postgres@localhost:5432/postgres"

Directory for scope configuration

The --scope flag defines which scope to use if it's defined in the config file using tuna secrets setup (more details about this command are described below). Default is . i.e. current directory.

For example, you have this description in your configuration:

cat ~/.config/tuna/tuna.yml
secrets:
scoped:
/home/user/src/api:
project: api-php
config: stage

This means that when you are in the /home/user/src/api directory, you don't need to pass --project and --config, as they are determined automatically relative to --scope=. current directory, and you can simply call tuna secrets download.

But if you are in a directory for which the scope is not defined, you will get an error:

$ pwd
/home/user/src/worker

$ tuna secrets download --format env --no-file
{"code":"BadRequest","error":"Validation failed: Incorrect value [fields=project,config]","request_id":"2wlgOjxclsn1yxVulEjPg2jKiQ5"}

But you can pass --scope of the required directory, for example:

$ tuna secrets download --format env --no-file --scope /home/user/src/api
API_TOKEN="PwZayIp9NpNntNYd2jkAAQgViM6dXdIm"
API_DB="postgres://postgres:postgres@localhost:5432/postgres"

Setup

Setting up the directory for scope configuration. To configure the current directory through a menu, run:

tuna secrets setup

Setting up scope without menu

As with download, in setup you can pass --project and --config and configure the environment without the graphical menu.

tuna secrets setup --project api-php --config stage

Setting up scope for a non-current directory

If you want to configure a non-current directory, pass the required path to the --scope flag.

tuna secrets setup --project api-php --config stage --scope /home/user/src/api

Run

Automatic application configuration with passing environment variables directly to the process.

tuna secrets run

In this case, tuna acts as a wrapper and runs your application with passing the necessary configuration to it. For example:

tuna secrets run -- yarn start

With explicit configuration passing

tuna secrets run --project api-php --config stage -- yarn start

With scope specification

tuna secrets run --scope /home/user/src/api -- yarn start

Automatic application restart when secret changes (watch)

If you pass the --watch flag, the client starts watching for secret changes in the API and if it changes, tuna will restart the process with the new configuration.

tuna secrets run --watch -- yarn start

This video best demonstrates the work:

In the video, we run this command:

tuna secrets run --watch -- bash -c 'while true; do echo -n "$(date -Is) [pid: $$] ==> " ; echo ${API_TOKEN} ; sleep 1; done'