Using the CLI tool in git workflows


How do I Install the BluBracket command line interface (CLI) tool?

Setting git hooks

In terminal, cd to the repo dir, then blubracket install-git-hooks

C:\Users\vbuzu\projects\sandbox>blubracket install-git-hooks
Successfully installed pre-commit hook to 'C:/Users/vbuzu/projects/sandbox/.git/hooks/pre-commit'

If git is setup to use global git hooks (specified by core.hooksPath git config), CLI will update/install the hook in that global folder.

Currently CLI will set only one hook, pre-commit.

Current limitations

CLI will install the pre-commit hook automatically only if the hook does not exist yet or the hook does exist and is implemented as a shell script (determined by the presence of #!/bin/sh or #!/usr/bin/env bash lines). In all other cases, e.g. if the hook is a python script, the CLI invocation must be added to the hook manually. It should be an equivalent of the follow shell command blubracket pre-commit "$@" || { exit "$?"; }: run blubracket command with pre-commit as the first parameter followed by all other parameters passed to the hook itself; exit/stop the hook on any non-zero exit codes from blubracket. integration

The CLI tool integrates with the hook management tool now. If it is detected that the pre-commit tool is used to manager the hooks, the CLI will add itself as one of the hooks to .pre-commit-config.yaml.

Note: Currently only the default configuration file is supported, if pre-commit tool is configured to use a different file, CLI will NOT add itself to it automatically. In that case, it can be done manually by adding following lines under repos key:

 - repo: local
      - id: blubracket
        name: BluBracket
        language: system
        entry: blubracket pre-commit
          - commit
        verbose: true
        always_run: true
        pass_filenames: false

Testing the BluBracket CLI commit hook

  • In your terminal, cd to your repository directory

  • Then add the following example secret into any file in your repository: myPassword="My$uperDuperS3cret!"

  • Now try to commit your change with git commit - your new BluBracket CLI hook should prevent the commit from happening.


Use your normal git workflow, edit and stage some files, then try to commit. If the changes have secrets, the commit will be blocked. For example:

C:\Users\vbuzu\projects\sandbox>git commit -m "test commit" -a
Blubracket found 4 secret(s)
C:\Users\vbuzu\projects\sandbox\src\app.cpp:7:11: password_assignment
C:\Users\vbuzu\projects\sandbox\tests\dir2\tests\file1.txt:11:16: bitbucket_oauth_key_base64
C:\Users\vbuzu\projects\sandbox\tests\dir2\tests\file1.txt:12:11: password_assignment
C:\Users\vbuzu\projects\sandbox\tests\dir2\tests\file1.txt:13:14: password_in_url


Sometimes it might be necessary to ignore secrets in some files or secrets of some types. To achieve this just create a .blubracket-ignore file in the root directory of the repo. The format of the file is similar to .gitignore. Empty lines and lines started with # are ignored. To ignore all secrets in a file, put a glob pattern, e.g. **/tests will ignore secrets found in all files in any tests directory and sub-directories. To ignore specific a secret type, e.g. any password like secrets, add a line like secret_type:password.*, where password.* is perl compatible regular expression. To ignore specific secret, add a line like secret_value:my_test_gcp_token where my_test_gcp_token is the real secret/token you want to ignore.


Current limitations:

  • negate mask (!) is not supported

  • .blubraket-ignore is read only from the root repo directory, placing it in a sub directory will have no effect.

Inline comments

In addition to .blubracket-ignore file, it is possible to mark a secret to be ignored by placing a “comment” on the same line as the secret. The comment/line has to have BluBracketIgnore string in it, please note that CLI will do case-sensitive comparison.

Possible workarounds for false positives

Ignoring whole folders and/or secret type all the time could be dangerous as it can be easy to miss secrets. The recommended ways to deal with false positives are inline comments or ignoring the particular secret using secret_value rule in the .blubracket-ignore file.

Adding checks for your own secrets

BluBracket supports hundreds of different secret types, but you can extend it to detect any pattern you want.

In a repo/clone folder create a file .blubracket/customregex.yml (if you want new secret checks be applicable for any repo, create the file in $HOME folder instead). The content of the file is a list of secrets to check. Each secret is defined by two properties: description and pattern. Description is textual name for the secret that will be displayed by CLI if the secret is detected. Pattern is a regex to match the secret. Here is an example of how to a check for SSNs:

- pattern: (?P<value>\d{3}-\d{2}-\d{4})
  description: simple_ssn


In addition to built-in secrets and custom secrets, the CLI supports the ability to define a different group of “secrets” related to PII (Personally Identifiable Information) such as Social Security Numbers (SSN), emails, URLs, IP-addresses, etc. This feature is fully customizable. Out of the box CLI defines several patterns but all can be disabled, or the corresponded action changed. Here is the default configuration file:

action: allow
disabled: false

- type: ssn
  description: Social Security Number
  pattern: \b(?P<ssn1>\d{3})-(?P<ssn2>\d{2})-(?P<ssn3>\d{4})\b
  exclude_if: |
    /000|666|9../.test(ssn1) ||
    ssn2 == "00" ||
    ssn3 == "0000"
  action: block

- type: email
  pattern: \b(?P<username>[a-z0-9!#'+^_~-]+(?:\.[a-z0-9!#'+^_~-]+)*)@(?P<domain>[a-zA-Z0-9-.]+)\b
  # exclude_if can be any valid JavaScript expression returns boolean value
  # it is not limited to a single expression, it can be even a full fledged function.
  # all matched groups defined in 'pattern' regex will be available as variables in the global execution context
  # the full matched value will be available as 'full_match' variable
  # Here is an example that uses a function: it will report only emails
  #exclude_if: |
  #  (function(){
  #    if (domain.toLowerCase() != "") return true;
  #    return false;
  #  })()
  disabled: true

- type: url
  description: URL
  pattern: \b(?:(?P<scheme>[a-zA-Z][a-zA-Z\d+-.]*):)(?:\/\/)?(?:(?P<userinfo>(?:[a-zA-Z\d\-._~\!$&'()*+,;=%]*)(?::(?:[a-zA-Z\d\-._~\!$&'()*+,;=:%]*))?)@)?(?P<host>[a-zA-Z\d\-.%]+)\b
  disabled: true

- type: ip_v4
  description: IPv4
  pattern: \b((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\b

- type: ip_v6
  description: IPv6
  pattern: (([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))

The configuration file can be global, for all the repos, it is located in ~/.blubracket/pii.yaml, or local, in repo’s .blubracket/pii.yaml file. If repo-local file exists, it will be used, otherwise the global file will be used. Upon launch, CLI with create the global file if it does not exist yet. After file has been created, it is OK to fully change it, CLI will not touch it anymore.

Sensitive words

In addition to checking secrets, CLI can check for sensitive/offensive words that might be good idea to avoid. Examples includes master, slave, etc. By default CLI only warns if a sensitive word has been found but allows commit to proceed. Sensitive Words can be configured in the similar way as PII Secrets. The configuration file name is ~/.blubracket/sensitive-words.yaml (or a repo-local alternative). Here is the default file:

  action: block
  disabled: false

  - type: master
    description: master
    pattern: \b(?i)(master(\w)*)\b
  - type: slave
    description: slave
    pattern: \b(?i)(slave)\b
  - type: whitelist
    description: whitelist
    pattern: \b(?i)(whitelist(ed|ing){0,1})\b
  - type: blacklist
    description: blacklist
    pattern: \b(?i)(blacklist(ed|ing){0,1})\b
  - type: whitebox
    description: whitebox
    pattern: \b(?i)(whitebox)\b
  - type: blackbox
    description: blackbox
    pattern: \b(?i)(blackbox)\b
  - type: whitehat
    description: whitehat
    pattern: \b(?i)(whitehat)\b
  - type: blackhat
    description: blackhat
    pattern: \b(?i)(blackhat)\b
  - type:  man_hours
    description: man-hours
    pattern: \b(?i)(man[ -]hours{0,1})\b
  - type: man_days
    description: man-days
    pattern: \b(?i)(man[ -]days{0,1})\b

Example output:

C:\Users\vbuzu\projects\sandbox>git commit -m "test" -a
BluBracket blocked 1 secret(s):
C:\Users\vbuzu\projects\sandbox\test2:8:27: custom_regex: simple SSN:
BluBracket allowed 1 sensitive word(s):
C:\Users\vbuzu\projects\sandbox\test2:8:4: Master: config: sensitive_keywords.action: allow

Commit signing

BluBracket can check that the commit is going to be signed or not and warn or block in case the commit is not signed. By default BluBracket only warns if commit is not signed.

Note: Blubracket only checks git config commit.gpgSign value and not -Soption passed to git commit command to determine signing status. The reason is that commit signing makes sense if all the commits are signed. Thus using commit.gpgSign is the most proper way to enable signing

Example Output:

C:\Users\vbuzu\projects\sandbox>git commit -m "test" -a
BluBracket allowed unsigned commit
Use `blubracket commit-signing configure` to enable commit signing
[master 94ca89a] test
 1 file changed, 2 insertions(+), 1 deletion(-)

Configure commit signing

In addition to checking is commit signed or not, BluBracket helps configuring signing if it is not done already. To do that use blubracket commit-signing configure command. This should be run inside a clone directory as it will configure the signing only for the one current repo/clone. To configure signing globally, for all the current and future clones, add --global flag. Internally CLI will create a gpg key if needed, will configure git to use it, and will point how to upload the key’s public key to git providers, like GitHub and GitLab.


  • CLI checks and configures gpg keys only, not S-MIME/X509

  • CLI will try to use gpg command already available on the user’s device. If gpg is not found:

    • on Linux, CLI will do nothing, as gpg actually expected to be installed by default

    • on Windows, CLI will use gpg from a git for Windows distribution, if available. CLI will NOT install gpg4Win

      • on Mac/OSX, CLI will install gnupg2 using brew. CLI will NOT install brew itself. Along side with gnupg2, CLI will install and configure pinentry-mac, so key management can be integrated with OSX keychain and commit signing works not only from terminal but from IDEs as well.
  • If a key needs to be generated, it is generated with default parameters (same as gpg –quick-gen-key command). Currently there is no way to customize this.

Example output:

C:\Users\vbuzu\projects\test-repo>blubracket commit-signing configure
Finding gpg... found: C:\Program Files\Git\usr\bin\gpg.exe
Checking gpg key for user-id 'John Doe <>' ...About to create a key for:
    "John Doe <>"

Continue? (Y/n)
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
We need to generate a lot of random bytes. It is a good idea to perform
some other action (type on the keyboard, move the mouse, utilize the
disks) during the prime generation; this gives the random number
generator a better chance to gain enough entropy.
gpg: key 25ADA7C6E06D60A0 marked as ultimately trusted
gpg: revocation certificate stored as '/c/Users/vbuzu/.gnupg/openpgp-revocs.d/AF06E23594DC979D3AC56B5625ADA7C6E06D60A0.rev'
public and secret key created and signed.

pub   rsa3072 2021-03-10 [SC] [expires: 2023-03-10]
uid                      John Doe <>
sub   rsa3072 2021-03-10 [E]

Configuring git to use commit signing...done
Getting public key for gpg key '25ADA7C6E06D60A0' ...done


Public Key has been copied to system clipboard. Next, add it to your git provider:
For GitHub: navigate to
For GitLab: navigate to

Binary files

The CLI can check that a “large” binary file is going to be committed and either ignore, warn, or block the commit depending on the file size. By default binary files less than 500 KB will be ignored; if more than 500 KB but less than 10 MB, CLI will warn but allow the commit; if more than 10 MB then the commit will be blocked. To disable only warning or blocking the size can be set to 0 (see configuration options below).

Sample output:

C:\Users\vbuzu\projects\test-repo>git commit -m "test"
BluBracket blocked 1 binary file
Blocked binary files:
C:\Users\vbuzu\projects\test-repo\bluscanner.exe: 81.2 MB
Consider using git-lfs to manage large binary files,

CLI configuration

By default CLI blocks secrets and allows sensitive words. It is possible to customize this behavior using config files. CLI loads config files from <repo>/.blubracket/config.yaml and ~/.blubracket/config.yaml. CLI mimics git config behavior where settings in a repo-local config overwrite settings in global config. Here is an example of the config file that has all the default values:

    disabled: false
    action: block

    disabled: false
    action: allow

    disabled: false
    allow_larger: 500KB
    block_larger: 10MB

Edit this page on GitHub