Store keys encrypted with code in git repo

Create a GPG pair

  • To generate a RSA key-pair

    1
    gpg --gen-key
  • Export your public key

    1
    gpg --export your.email@address.com --armor > public-key.gpg
  • Import the public key of someone else (to share the secret with them)

    1
    gpg --import public-key.gpg

Git-crypt

Install

  • Check git-crypt
  • Manual
    1
    2
    3
    4
    git clone https://www.agwa.name/git/git-crypt.git
    cd git-crypt
    make
    make install

Set up

  • Configure a repository

    1
    2
    cd repo
    git-crypt init
  • Specify files to encrypt by creating a .gitattributes file in the repository

    1
    2
    3
    secretfile filter = git-crypt diff=git-crypt
    *.key filter = git-crypt diff=git-crypt
    secretdir/** filter = git-crypt diff=git-crypt
    • Like a .gitignore file, it can match wildcards and should be checked into the repository.
    • Make sure you don’t accidentally encrypt the .gitattributes file itself (or other git files like .gitignore or .gitmodules).
    • Make sure your .gitattributes rules are in place before you add sensitive files, or those files won’t be encrypted!

Share (with GPG Mode)

  • Share the repository with others (or with yourself) using GPG

    1
    2
    3
    # USER_ID can be a key ID, a full fingerprint, an email address...
    git-crypt add-gpg-user USER_ID
    # a GPG-encrypted key file is added and commited in the `.git-crypt` directory
  • After cloning a repository with encrypted files, unlock it

    1
    git-crypt unlock

Git secret

Install

  • Check git-secret
  • Manual
    1
    2
    3
    git clone https://github.com/sobolevn/git-secret.git git-secret
    cd git-secret && make build
    PREFIX="/usr/local" make install

Setup

  • Add the keyrings and information to make git-secret hide and reveal files in the repo
    1
    2
    3
    # create the .gitsecret/ dir
    git secret init
    # it will also add the file .gitsecret/keys/random_seed` to your `.gitignore`
  • Add the first user to the git-secret repo keyring
    1
    git secret tell your@gpg.email
  • Add files you wish to encrypt inside the git-secret repository
    1
    2
    git secret add <filenames...>
    # those unencrypted files will also be added to .gitignore
  • Encrypt with the public-keys described by the git secret tell command
    1
    2
    # it is recommended to add this command to pre-commit hook
    git secret hide
  • Decrypt (it will require password)
    1
    2
    3
    4
    # decrypt
    git secret reveal
    # just show decrypted on screen
    git secret cat

Share (with GPG Mode)

  • Get their gpg public-key (the secret key is not needed)
  • Import this key into your gpg keyring (in ~/.gnupg or similar)
    1
    gpg --import KEY_NAME.txt
  • Add this person to your secrets repo
    1
    2
    # tell email address associated with the public key
    git secret tell persons@email.id
  • Re-encrypt the encrypted files
    1
    2
    # -d deletes the unencrypted after encrypting
    git secret reveal; git secret hide -d
  • Check it worked as expected by decrypting
    1
    git secret reveal

Dotenv storage

Install

Setup

  • create a .env file
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    # a comment that will be ignored.
    REDIS_ADDRESS=localhost:6379
    MEANING_OF_LIFE=42
    MULTILINE_VAR="hello\nworld"
    # you may prefix each line with the word export
    # which is totally ignored by this library
    CONFIG_PATH=${HOME}/.config/foo
    DOMAIN=example.org
    EMAIL=admin@${DOMAIN}
    DEBUG=${DEBUG:-false}
  • Load environment variables from a file named .env in the current directory or any of its parents or from the path specificied
    1
    2
    load_dotenv()
    # after this any call from os.getenv will get them

Usage example

  • Add to settings.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    # settings.py
    from dotenv import load_dotenv
    load_dotenv()

    # OR, the same with increased verbosity
    load_dotenv(verbose=True)

    # OR, explicitly providing path to '.env'
    from pathlib import Path # Python 3.6+ only
    env_path = Path('.') / '.env'
    load_dotenv(dotenv_path=env_path)
  • After load, you may call the environment variables using getenv

    1
    2
    3
    4
    # settings.py
    import os
    SECRET_KEY = os.getenv("EMAIL")
    DATABASE_PASSWORD = os.getenv("DATABASE_PASSWORD")

lsusb

  • The Linux lsusb command lists information about the USB devices connected to a system, but sometimes the information is incomplete (see line 5 lacks manufracturer).

    1
    2
    3
    4
    5
    6
    $ lsusb
    Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
    Bus 001 Device 004: ID 046d:082c Logitech, Inc.
    Bus 001 Device 003: ID 0951:16d2 Kingston Technology
    Bus 001 Device 002: ID 18f8:1486
    Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

USB ID Repository

Check repository

Location

  • The USB ID database is stored in a file called usb.ids.
  • This location may vary depending on the Linux distribution.
    • Ubuntu 18.04: /var/lib/usbutils

Update your USB IDs

  • Update

    1
    $ sudo update-usbids
  • If a new file is available, it will be downloaded. The current file will be backed up and replaced by the new one.

    1
    2
    3
    4
    5
    6
    $ ls -la
    total 1148
    drwxr-xr-x 2 root root 4096 Jan 15 00:34 .
    drwxr-xr-x 85 root root 4096 Nov 7 08:05 ..
    -rw-r--r-- 1 root root 614379 Jan 9 15:34 usb.ids
    -rw-r--r-- 1 root root 551472 Jan 15 00:34 usb.ids.old

Premiliminar steps

  • You will need a certificate file CertEmulationCA.crt
  • It will be useful to also have it as a .pem, so you can transfor it via:
    1
    openssl x509 -in CertEmulationCA.crt -out CertEmulationCA.pem -outform PEM

Fixes

Python

  • pip

    • Unconfortabe option since you need to do it on every action

      • Work with SSL disabled

        1
        2
        pip install --trusted-host pypi.org \
        --trusted-host files.pythonhosted.org pip boto3
      • Add the certiticate on every call

        1
        2
        3
        4
        5
        python config --set ssl_verify \
        "%USERPROFILE%\.aws\CertEmulationCA.crt"

        pip --proxy http://proxy.threatpulse.net:8080 \
        --cert="%USERPROFILE%\.aws\CertEmulationCA.crt" install moto
    • Permanent option by adding the certificate to the profile variable

      1
      pip config set global.cert "%USERPROFILE%\.aws\CertEmulationCA.crt"
  • requests

    • Permanent option by adding the certificate to the profile variable
      1
      SETX REQUESTS_CA_BUNDLE "%USERPROFILE%\.aws\CertEmulationCA.pem"

AWS-CLI

  • Work with SSL disabled

    • On CLI
      1
      aws --no-verify-ssl s3 ls
    • On boto3: while you are runnnig it on your computer, you must deactivate the SSL on the client (don’t forget to remove this “disable flags” before uploading the code somewhere else)
      1
      2
      3
      4
      session = boto3.session.Session(profile_name=profile_name)
      rds_client = session.client("rds", verify=False, use_ssl=False)
      cloudwatch_client = session.client(
      "cloudwatch", verify=False, use_ssl=False)
  • Add certiticate manually

    • Add environment variable
      1
      2
      # add as environment variable and reboot
      SETX AWS_CA_BUNDLE "%USERPROFILE%\.aws\CertEmulationCA.pem"

Git

  • Option 1: Generate a virtual certificate variable

    1
    git config --global http.sslCAInfo %USERPROFILE%/.aws/CertEmulationCA.crt
  • Option 2: You may also add it directly to the .gitconfig file

    1
    2
    [http]
    sslCAInfo = %USERPROFILE%/.aws/CertEmulationCA.crt

Manual fix for Postman

  • The .crt file doesn’t work properly, so you will need a .pem version of it.
  1. Transform the .cert file into a .pem
    1
    2
    # convert crt to pem
    openssl x509 -in CertEmulationCA.crt -out CertEmulationCA.pem -outform PEM
  2. Go to settings, certificates, and set the CA certificates flag as ON
  3. Add the .pem file

Extra: CMD variable

  • Add variable for Terminus
    1
    SETX CMDER_ROOT "%USERPROFILE%\Dev\Apps\cmder"

Install and configure cypress

  1. Add dependency

    1
    npm install -D cypress cypress-axe
  2. Configure plugin (cypress/plugins/index.js)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    module.exports = (on, config) => {
    on('task', {
    log(message) {
    console.log(message)

    return null
    },
    table(message) {
    console.table(message)

    return null
    }
    })
    }
  3. Configure suport: create a cypress/support/index.js file containing:

    1
    import 'cypress-axe'

Creating the accessibility test

Cypress will visit each page of the project,a nd it will test each example in the page.

  1. Create the Cypress configuration file (cypress.json), with video recording disabled:

    1
    2
    3
    4
    {
    "baseUrl": "http://localhost:8000/",
    "video": false
    }
  2. Create the test file (cypress/integration/accessibility.spec.js)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    // get failing elements info
    const terminalLog = (violations) => {
    cy.task(
    'log',
    `${violations.length} accessibility violation${
    violations.length === 1 ? '' : 's'
    } ${violations.length === 1 ? 'was' : 'were'} detected`
    )
    // pluck specific keys to keep the table readable
    const violationData = violations.map(
    ({ id, impact, description, nodes }) => ({
    id,
    impact,
    description,
    nodes: nodes.length
    })
    )

    cy.task('table', violationData)
    }

    const routes = ['badge.html', 'button.html'];

    describe('Component accessibility test', () => {
    routes.forEach((route) => {
    const componentName = route.replace('.html', '');
    const testName = '${componentName}' +
    'has no detectable accessibility violations on load';

    it(testName, () => {
    cy.visit(route);
    cy.injectAxe();

    cy.get('.cypress-wrapper').each((element, index) => {
    cy.checkA11y(
    '.cypress-wrapper',
    {
    runOnly: {
    type: 'tag',
    values: ['wcag2a'],
    },
    }
    // if you want to get the violations log
    terminalLog,
    );
    });
    });
    });
    });
    • Standards to test
      Tag Name Accessibility Standard / Purpose
      wcag2a WCAG 2.0 Level A
      wcag2aa WCAG 2.0 Level AA
      wcag21a WCAG 2.1 Level A
      wcag21aa WCAG 2.1 Level AA
      best-practice Common accessibility best practices
      wcag*** WCAG success criterion e.g. wcag111 maps to SC 1.1.1
      ACT W3C approved Accessibility Conformance Testing rules
      section508 Old Section 508 rules
      section508.*.* Requirement in old Section 508
  3. Create coomand inside the package.json:

    1
    2
    3
    {
    "test": "cypress"
    }
  4. Run it

    1
    2
    3
    4
    5
    # run headless mode
    npm run cypress run

    # use Cypress runner
    npm run cypress open
0%