Command Line Interface
You can download the SAFE CLI from the Download SAFE CLI page.
The CLI setup will generate 2 files which allows SAFE to run in your CI/CD:
- A fingerprint file that uniquely identifies the project without containing any sensitive information. To generate a correct fingerprint file, please makes sure to compile your codebase. Please send this file to safe@erlang-solutions.com to help generate the License for the project.
- A config.json which is generated in you repository under the
.safefolder. Please make sure to commit it.
The CLI operates entirely offline and never transmits any data from the machine on which it runs.
safe setup Command
You should first compile your codebase with the debug_info flag.
In case of a Rebar3 or Mix project (Elixir), this option is enabled by default.
If you have a mix project please compile it in your target environemtn (prod, dev..) and run the following command:
./safe setup --name NAME
--root ROOT
--path _build/prod/lib
--app APP1
--app APP2
For Rebar:
./safe setup --name NAME
--root ROOT
--path _build/default/lib
--app APP1
--app APP2
Usage
safe setup --name NAME --root ROOT --app APP
[--app APP ...] [--path PATH ...]
[--safe-config-output CONFIG_OUTPUT]
[--fingerprint-output FINGERPRINT_OUTPUT]
Arguments
Required:
-
--name NAME
The name of your project. Used as an identifier in SAFE config. -
--root ROOT
The root directory of your project. Can be absolute or relative. -
--app APP(repeatable)
At least one Erlang app name to analyze.
Use multiple--appflags to include more apps.
Optional:
-
--path PATH(repeatable)
Additional directories to search for apps.
Defaults to.if not specified.
Must be relative to the path given in--root. Useful for_build,apps/, or custom lib folders. -
--safe-config-output CONFIG_OUTPUT
Custom path for the generatedconfig.json.
If not set, defaults to<ROOT>/.safe/config.json.
Relative paths are resolved from--root. -
--app-includes APP=PATH(repeatable)
Add an extra include directory for a specific app. Format:APP_NAME=PATH, wherePATHis relative to--root. Use multiple--app-includesflags for multiple entries.
Sets theadditional_includesfield in the generated config. -
--fingerprint-output FINGERPRINT_OUTPUT
Where to writefingerprint.json.
Defaults tofingerprint.jsonin the current working directory.
Relative paths are resolved from the working directory.
Examples
Multiple apps, including a _build path:
safe setup --name myproject --root ~/my_project --app foo --app bar --path _build/dev/lib
Custom config output path:
safe setup --name myproject --root ~/my_project --app foo --safe-config-output ./myconfig.json
Absolute config path:
safe setup --name myproject --root ~/my_project --app foo --safe-config-output /tmp/config.json
Generate fingerprint file in desktop:
safe setup --name myproject --root ~/my_project --app foo --fingerprint-output ~/Desktop/fingerprint.json
Add extra include paths for specific apps:
safe setup --name myproject --root ~/my_project --app foo --app bar \
--app-includes foo=priv/include --app-includes bar=vendor/include
- You must provide at least one
--appor the command will fail. --pathhelps in finding your compiled application (e.g._build/dev/lib,apps/, etc).
Once the setup is complete and you have generated a fingerprint file, please send it via email to safe@erlang-solutions.com. In your message, specify whether you would like to proceed with a monthly or yearly license.
safe setup gleam Command
For a Gleam project, safe setup gleam replaces the safe setup form above: it reads the
project name and version from gleam.toml and works out the root and app for you, so --name,
--root and --app are not needed.
While Gleam analysis is in beta, safe analyse runs a Gleam project with no license at all — with
or without a config file. See safe analyse on a Gleam project
below. Run safe setup gleam when you need a report file, SARIF or Checkmarx output, or
additional_includes.
Build the project first — SAFE analyses the compiled build/dev/erlang output:
gleam build
safe setup gleam
Usage
safe setup gleam [--root ROOT]
[--safe-config-output CONFIG_OUTPUT]
[--fingerprint-output FINGERPRINT_OUTPUT]
Run safe setup gleam help for the built-in help.
Arguments
Optional:
-
--root ROOTRoot folder of the Gleam project — the directory containinggleam.toml. Defaults to the current directory. -
--safe-config-output CONFIG_OUTPUTWhere to write the generatedconfig.json. Defaults to.safe/config.jsoninsideROOT. A relative path is resolved fromROOT. -
--fingerprint-output FINGERPRINT_OUTPUTWhere to writefingerprint.json. Defaults tofingerprint.jsonin the current working directory. A relative path is resolved from the working directory, not fromROOT.
Examples
safe setup gleam
safe setup gleam --root ~/my_gleam_project
safe setup gleam --safe-config-output ./myconfig.json
safe setup gleam --fingerprint-output /tmp/fingerprint.json
Gleam-specific errors
Each of these is fatal: nothing is written and the command exits 1.
No gleam.toml found at <root>. `safe setup gleam` must be run from a Gleam project root (or pass --root).
You are not in a Gleam project root. cd to it, or pass --root.
Gleam project detected at <root> but no compiled output was found at build/dev/erlang.
Run `gleam build` first, then re-run `safe setup gleam`.
The project has not been built for the Erlang target. Run gleam build.
Failed to read gleam.toml: <reason>. Please ensure the file is valid TOML and has a 'name' field.
gleam.toml is not valid TOML, or has no name field.
The checks safe setup runs for every project type apply here too, so its errors — missing
debug_info, no .app file, no source files found — can appear for a Gleam project as well.
Analysis itself needs no Gleam-specific flags — once .safe/config.json exists, safe analyse
behaves the same for every project type, except that the license stays free during the beta. See
Gleam projects for the full workflow and
config.json for the generated config.
safe analyse Command
Runs security analysis on your project. Exits with a non-zero code if vulnerabilities are found.
Usage
safe analyse [--config-path CONFIG_PATH]
safe analyse [--config-json CONFIG_JSON --project-root PROJECT_ROOT]
[--no-abstract-code-check]
Arguments
Optional:
-
--config-path CONFIG_PATH
Path to the SAFE configuration file (typically.safe/config.json).
Defaults to$PWD/.safe/config.jsonif not provided. -
--config-json CONFIG_JSON
Provide the JSON config directly on the command line instead of a file.
Requires--project-root. -
--project-root PROJECT_ROOT
Root path of your project. Required when using--config-json. -
--no-abstract-code-check
Skip the check that verifies BEAM files were compiled withdebug_info.
Use only if you are certain your build includes abstract code.
Exit Codes
| Code | Meaning |
|---|---|
0 | Analysis completed — no vulnerabilities found |
1 | An error occurred (configuration issue, analysis failure) |
2 | Analysis completed — vulnerabilities found |
safe analyse on a Gleam project
Gleam analysis is free while it is in beta. Whenever safe analyse finds a Gleam project — a
gleam.toml naming it, and every application in scope compiled by the Gleam compiler — it analyses
it without a license, with or without a .safe/config.json:
gleam build
safe analyse
✓ No SAFE license required — analysing this Gleam project under the free beta.
✓ SAFE license is valid until 2027-03-31.
Info: 6 months, 24 days left in the Gleam free beta (ends 2027-03-31).
Run without a config the report is printed to the console only, and --no-abstract-code-check has
no effect — the abstract code check always runs. With a config, output and flags behave as they do
for any project. Either way SAFE_LICENSE is not read, and the beta covers projects up to 100,000
lines of code. See Gleam projects.
safe analyse clean
Wipes the internal SAFE database — the working state maintained between runs by the analysis engine.
safe analyse clean
The command takes no arguments. Use it when analysis results look incorrect after a significant
project restructure, or when you want to guarantee the next safe analyse starts from scratch.
| Code | Meaning |
|---|---|
0 | Database cleaned successfully |
1 | An error occurred while resetting the database |