How to Get Started

We built the Spectral platform from the ground up to have fantastic developer experience (DX). Spectral Scan is a single self-contained binary, that's easy to get and use.

Your first scan

You can get Spectral in one of the following ways, for your convenience:

Homebrew on mac:

brew tap spectralops/tap && brew install spectral

Or, universal installer for mac/Linux:

curl -L https://<YOUR_SPECTRAL_DOMAIN>/latest/x/sh | sh

replace <YOUR_SPECTRAL_DOMAIN> with the domain you use to login to SpectralOps (get.spectralops.io, app.spectralops.io etc)

And for Windows PowerShell:

iwr https://<YOUR_SPECTRAL_DOMAIN>/latest/ps1 -useb | iex

All of the above are great. Pick the one you like ๐Ÿค˜

๐Ÿ‘

Enterprise customers can use their DSN to get the Spectral enterprise offering, for example: curl -L https://<YOUR_SPECTRAL_DOMAIN>/latest/sh?dsn=<YOUR_DSN> | sh

Spectral offers several scanning engines. You can read all about it in the Products section.
We'll focus on the Spectral Secret Scanning for this example, so go a head and make your first scan:

$ mkdir spectral-test && cd spectral-test
$ $HOME/.spectral/spectral scan --dsn <YOUR_DSN>
โœ” no matches found
  scanned 0 bytes and 0 files in 2ms

๐Ÿ‘

As a security best-practice, you should never run curl | sh blindly. Feel free to inspect our install script (it's a shell script) before running. We also recommend using our very own preflight to verify checksums.

๐Ÿฆธโ€โ™€๏ธ You're good to go! Looks like everything downloaded right, and things are running!

Your first match

Assuming you're still in spectral-test, let's create a dummy secret:

$ echo AKIAIOSFODNN7EXAMPLX > foo.txt
$ $HOME/.spectral/spectral scan
/Users/superhero/spectral-test/foo.txt
        0:20 Error        Visible AWS Key CLD001

We see our match. We have our file, a location (0:20), severity (Error), description and detector code (CLD001).

๐Ÿ‘

Spectral is secure by default

We never dump the actual secret or key to the console, or anywhere. If you want to see it, add a SPECTRAL_SHOW_MATCH=1 environment flag before running.

$ $HOME/.spectral/spectral scan
...
[your-project] SVC006 - Exposed PubNub Secret on Client Side App
- res/values/strings.xml

Kicking the tires ๐Ÿ’ฅ

To get an idea of the amount of stacks Spectral can analyze, you can use our codesec-goat repo.

๐Ÿ“˜

What's a "goat" project?

A common saying is that if your fence won't hold water, it won't hold a goat. Animals are very creative, and will find a way around your barriers. In the same funny analogy, a goat repo demonstrates creativity and deliberate security issues that you might not expect.

Assuming you unzipped codesec-goat somewhere, let's run Spectral scan:

$ cd codesec-goat
$ $HOME/.spectral/spectral scan
โžœ  spectral-goat git:(master) spectral scan

                              __                .__
    ___________  _____ ______/  |_____________  |  |
   /  ___\____ \/  _  /  ___\   __.|  __/\__  \ |  |
   \___ \|  |_> \  ___\  \___|  |  |  |   / __ \|  |_
  /______|   __/ \_____\_____|__|  |__|  /______|___/ops.io
         |__|

     Spectral: 1.9.131 (1602)
           OS: macos (x86_64)
     is_audit: No
          DSN: Yes (from param/env)
         mode: interactive
    is_public: n/a
         repo: https://github.com/spectral-corp/spectral-goat
       branch: master
   remote_cfg: Yes

High: Visible Google API Key [CLD004]
    โ•ญโ”€[src/infra/google-api.json:24:27]
    โ”‚
 24 โ”‚           "current_key": "AIzaSyAM*******************************"
    ยท                           โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                              โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Google API Key
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Visible Google cloud host [CLD030]
    โ•ญโ”€[src/infra/google-api.json:18:25]
    โ”‚
 18 โ”‚           "client_id": "344570128040-0a*********************************************************",
    ยท                         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                                             โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Google cloud host
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Visible Google cloud host [CLD030]
    โ•ญโ”€[src/infra/google-api.json:31:29]
    โ”‚
 31 โ”‚               "client_id": "344570128040-0a*********************************************************",
    ยท                             โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                                                 โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Google cloud host
โ”€โ”€โ”€โ”€โ•ฏ

High: Google Client ID URL [GOOG001]
    โ•ญโ”€[src/infra/google-api.json:18:25]
    โ”‚
 18 โ”‚           "client_id": "344570128040-0a*********************************************************",
    ยท                         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                                             โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Google Client ID URL
โ”€โ”€โ”€โ”€โ•ฏ

High: Google Client ID URL [GOOG001]
    โ•ญโ”€[src/infra/google-api.json:31:29]
    โ”‚
 31 โ”‚               "client_id": "344570128040-0a*********************************************************",
    ยท                             โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                                                 โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Google Client ID URL
โ”€โ”€โ”€โ”€โ•ฏ

High: Visible Private Key [KEYS002]
    โ•ญโ”€[src/infra/rsa.key:1:1]
    โ”‚
  1 โ”‚ โ•ญโ”€โ–ถ -----BEGIN RSA PRIVATE KEY-----
    โ‹ฎ โ‹ฎ
 27 โ”‚ โ”œโ”€โ–ถ *****************************
    ยท โ”‚
    ยท โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Private Key
โ”€โ”€โ”€โ”€โ•ฏ

High: Visible Private Key [KEYS002]
    โ•ญโ”€[src/infra/id_rsa:1:1]
    โ”‚
  1 โ”‚ โ•ญโ”€โ–ถ -----BEGIN OPENSSH PRIVATE KEY-----
    โ‹ฎ โ‹ฎ
 38 โ”‚ โ”œโ”€โ–ถ *********************************
    ยท โ”‚
    ยท โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Private Key
โ”€โ”€โ”€โ”€โ•ฏ

High: MemCached configured to run as root [MEMC002]
    โ•ญโ”€[src/infra/memcache/memcached.conf:30:1]
    โ”‚
 30 โ”‚ *******
    ยท โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€
    ยท    โ•ฐโ”€โ”€โ”€โ”€โ”€ MemCached configured to run as root
โ”€โ”€โ”€โ”€โ•ฏ

Medium: MySQL config file contains a visible report password [MYSQL003]
    โ•ญโ”€[src/infra/mysql/mysqld.cnf:24:21]
    โ”‚
 24 โ”‚ report-password =   **** # bad password
    ยท                     โ”€โ”€โ”ฌโ”€
    ยท                       โ•ฐโ”€โ”€โ”€ MySQL config file contains a visible report password
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Redis configuration include one or more users with a visible password [REDIS001]
    โ•ญโ”€[src/infra/redis/redis.conf:16:31]
    โ”‚
 16 โ”‚ user shai on +@all -DEBUG ~* >************ -@all
    ยท                               โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€
    ยท                                     โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€ Redis configuration include one or more users with a visible password
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Redis configured to worldwide listening [REDIS003]
   โ•ญโ”€[src/infra/redis/redis.conf:8:1]
   โ”‚
 8 โ”‚ bind *****************
   ยท โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   ยท            โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Redis configured to worldwide listening
โ”€โ”€โ”€โ•ฏ

Informational: Potential cryptographic key bundle file [SENF006]
    โ•ญโ”€[/Users/jenia/dev/spectral-goat/src/notebook/docs/source/ipython_security.asc]
    โ”‚
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Google Services JSON File [SENF086]
    โ•ญโ”€[/Users/jenia/dev/spectral-goat/src/infra/google-api.json]
    โ”‚
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Found a SQLite database file [SENF106]
    โ•ญโ”€[/Users/jenia/dev/spectral-goat/src/notebook/notebook/tests/test_hist.sqlite]
    โ”‚
โ”€โ”€โ”€โ”€โ•ฏ

Informational: Exposed Sentry DSN [SVC016]
   โ•ญโ”€[src/frontend/sentry.js:9:9]
   โ”‚
 9 โ”‚   dsn: 'https://3427253**********************************************************',
   ยท         โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
   ยท                                             โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Exposed Sentry DSN
โ”€โ”€โ”€โ•ฏ

High: Visible Terraform Azure Database password [TF010]
    โ•ญโ”€[src/multicloud/terraform/azure/main.tf:12:35]
    โ”‚
 12 โ”‚   administrator_login_password = "4-v3r*****************"
    ยท                                   โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                              โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Terraform Azure Database password
โ”€โ”€โ”€โ”€โ•ฏ

Medium: Visible Terraform Azure Database username [TF011]
    โ•ญโ”€[src/multicloud/terraform/azure/main.tf:11:35]
    โ”‚
 11 โ”‚   administrator_login          = "*************"
    ยท                                   โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€
    ยท                                         โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Visible Terraform Azure Database username
โ”€โ”€โ”€โ”€โ•ฏ

โœ– found 17 matches
  scanned 10515636 bytes and 557 files in 507ms

You'll see a wealth of findings ranging around the following topics:

  • Sensitive data
  • Credentials and access controls
  • Misconfiguration
  • Tech stack bad practices

๐Ÿฆธโ€โ™€๏ธ Human error is, well, complicated. You may detect SQL injection, update libraries every day, still -- takes one innocent mistake to expose your team to unneeded risk.

Our idea is: we build an understanding of everything that can lead to security minded human errors, and poses a high risk. Then we look for it, detect it, and help you block and mitigate it.

Make it stick

Now that you've seen what Spectral can do, you can plug it into your development processes so that you're safe all the time. Like any new process for a dev team, we need to make the process stick.

One of the most recommended places to integrate Spectral to is your CI.

๐Ÿ‘

Never hold up a build

We build Spectral for performance. Every day. That's actually a business KPI of ours. Spectral scans an average sized repo in a second. Thanks to Rust and our low-level engineers, we're very happy.

Let's see how Spectral works in CircleCI (we support every popular CI there is today):

Before

version: 2
jobs:
  build:
    docker:
      - image: circleci/node:latest
    steps:
      - checkout
      - run: yarn test

Now you need to add your TEAM_KEY and your SPECTRAL_DSN to CircleCI (look here for how to do that). And use this configuration:

version: 2
jobs:
  build:
    docker:
      - image: circleci/node:latest
    steps:
      - checkout
      - curl -L 'https://get.spectralops.io/latest/sh?key=${TEAM_KEY}' | sh
      - $HOME/.spectral/spectral run
      - run: yarn test

๐Ÿ‘

As a security best-practice, you should never run