Secrets
In this tutorial you will learn how to use secrets in Toit projects.
Introduction
Many online services require a secret to be able to access them. For example, a database might require a password, or a service might require an API key. For open-source projects (and often for closed-source ones too) these secrets should not be stored in the source code.
In the remainder of this tutorial we will show a simple way of storing secrets in Toit projects without ending up storing them in the version control system.
Prerequisites
We assume that you have set up your development environment as described in the IDE tutorial.
We also assume that you are familiar with running Toit programs. If not, have a look at the Hello world tutorial.
Note that you can do this tutorial without a device. In that case,
you need to use the -d host option whenever you invoke
jag run. The program will then run on your computer instead of on
a device.
The project
We will assume an API key "123456" that we want to use in our program.
A simple program client.toit that uses this API key could look like this:
To simplify things we simply "use" the API key by printing it.
Storing the secret for devices
A common way of passing secrets to programs is to use environment. However, when flashing a program to a device, the environment is not available.
Instead, we can store the secret in a separate file that isn't checked in.
A secrets file
The most straight-forward way of storing the secret is to create a file
called secrets.toit with the following content:
The original client.toit program can then be changed to the following:
import .secrets main: secret-api-key := API-KEY // Imported from secrets. print "Using the API-KEY now: $secret-api-key"
The secrets.toit file should not be checked into version control.
One problem with this approach is that there isn't a good way to distinguish between secrets for different environments. For example, if we have a development environment and a production environment, we might want to use different secrets in the two environments.
The next section shows a way to solve this problem.
Using a separate entry file
Whereas the previous approach imported the secrets file directly, we can instead create a separate entry file that passes the secret to the main program.
Change the original program to the following:
Then create a file called client-production.toit with the following content:
The main function in client-production.toit simply calls the main function
in client.toit with the API key as an argument. The client-production.toit file
should not be checked into version control.
This approach makes it easy to have different secrets for different
environments. For example, we can create a client-dev.toit file with
different secrets for the development environment.
Since there is now more boilerplate code, we should create a template
for the client-X.toit files. For example, a client-template.toit file
could look like this:
Whenever we want to create a new client-X.toit file, we can simply
copy the client-template.toit file and replace <API-KEY> with the
actual API key.
At this point, we should add the client-template.toit file to version
control, and then ignore the client-X.toit files. This can
be done by adding the following line to the .gitignore file:
Using the environment
When running a program on the desktop, we can use the environment to
pass secrets to the program. In that case we need the
host package. Install it by running the following command:
See the package tutorial for more information.
The host package provides the os library which gives access to
the environment.
We can add a few more lines to the original client.toit program to
use the environment:
import host.os
main:
api-key := os.env.get "API_KEY"
if not api-key or api-key == "":
print "Please set the API_KEY environment variable."
return
main api-key
main api-key:
print "Using the API-KEY now: $api-key"Since we still have a main function that takes an api-key argument,
we can still use the client-production.toit file to run the program
on a device. However, we can now also run the program on the desktop
by setting the API_KEY environment variable.
Conclusion
In this tutorial we have seen how to use secrets in Toit projects. We have seen how to store secrets in a separate file, and how to use the environment to pass secrets to programs.