Skip to content

PierreBeucher/novops

Repository files navigation

Novops

novops-features

Novops, the universal secret and configuration manager for development, applications and CI.

  • Secret management: Load secrets safely from any source, including Hashicorp Vault, AWS, GCloud, Azure, SOPS and more
  • Configuration as code: Seamlessly manage and set secure files and environment variables for your local development, applications, and CI pipelines.
  • Security: Load secrets safely in-memory and keep them only for as long as they are needed to avoid mishandling or spreading sensitive data.
  • Universal: Designed to be versatile and flexible, meeting a wide range of secret management needs across different platforms and tools.
  • Free and Open Source: Novops is free and open-source - and will always be.

📖 Visit website for full documentation and examples


Getting Started

Let's deploy an application with secret password and SSH key from Hashicorp Vault and temporary AWS credentials.

Install Novops (or use another method):

sh -c "$(curl --location https://raw.githubusercontent.com/PierreBeucher/novops/main/install.sh)"

Create .novops.yml and commit it safely - it does not contain any secret:

environments:

  # Your development environment.
  # Novops supports multiple environments:
  # you can add integ, preprod, prod... 
  # with their own config.
  dev:
    
    # Environment variables for dev environment
    variables:
      
      # Fetch Hashicorp Vault secrets
      - name: DATABASE_PASSWORD
        value:
          hvault_kv2:
            path: app/dev
            key: db_password

      # Set plain string as config
      - name: DATABASE_USER
        value: postgres
    
    # Load files safely in-memory.
    # Environment variable APP_SSH_KEY
    # will point to secure in-memory file 
    files:
      - variable: APP_SSH_KEY 
        content:
          hvault_kv2:
            path: app/dev
            key: ssh_key
    
    # Generate temporary AWS credentials for an IAM Role
    # Provide environment variables:
    # - AWS_ACCESS_KEY_ID
    # - AWS_SECRET_ACCESS_KEY
    # - AWS_SESSION_TOKEN
    aws:
      assume_role:
        role_arn: arn:aws:iam::12345678910:role/dev_deploy

Run commands with secrets and configs and discard them as soon as they're not needed anymore:

# bash: source with process substitution
source <(novops load)

# zsh / ksh: source with process substitution
source =(novops load)

# Run sub-process directly
novops run -- sh # or any other command, like 'terraform apply'

# load in .env file (novops creates a symlink pointing to secure temporary file)
novops load -s .envrc && source .envrc

Secrets are available as environment variables and secure in-memory files:

echo $DATABASE_PASSWORD
# passxxxxxxx

echo $APP_SSH_KEY
# /run/user/1000/novops/... (in a secure tmpfs directory)

env | grep AWS
# AWS_ACCESS_KEY_ID=AKIAXXX
# AWS_SECRET_ACCESS_KEY=xxx
# AWS_SESSION_TOKEN=xxx

🔐 Security

Secrets are loaded temporarily as environment variables or in a protected tmpfs directory and kept only for as long as they are needed.

See Novops Security Model for details

Features

  • Securely load secrets in protected in-memory files and environment variables
  • Generate temporary credentials and secrets
  • Fetch secrets from anywhere: Hashicorp Vault, AWS, Google Cloud, Azure, SOPS and more. Avoid syncing secrets between local tool, CI/CD, and Cloud secret services.
  • Feed secrets directly to command or process with novops run, easing usage of tools like Terraform, Pulumi, Ansible...
  • Manage multiple environments: dev, preprod, prod... and configure them as you need.
  • Easy installation with fully static binary or Nix

Modules

Novops uses modules to load and generate temporary secrets from various platforms and providers. Configure them in .novops.yml:

Hashicorp Vault

Supported Hashicorp Vault Secret Engines:

  • Key Value v1/v2
  • AWS: generate temporary STS credentials

See Hashicorp Vault module reference

environments:
  dev:
    
    variables:
      # KV2 Secret Engine
      - name: APP_PASSWORD
        value:
          hvault_kv2:
            path: "myapp/dev/creds"
            key: "password"
      
      # KV1 Secret Engine
      - name: APP_TOKEN
        value:
          hvault_kv1:
            mount: kv1
            path: "otherapp/dev/creds"
            key: "token"

    # AWS temporary creds with Vault
    hashivault:
      aws:
        name: dev_role
        role_arn: arn:aws:iam::111122223333:role/dev_role

AWS: Secrets Manager, Temporary Credentials and Parameter Store

Multiple AWS services are supported:

  • Secrets Manager
  • STS Assume Role for temporary IAM Role credentials
  • SSM Parameter Store

See AWS module reference

environments:
  dev:
    
    # Temporary IAM Role credentials. Output variables
    # AWS_ACCESS_KEY_ID
    # AWS_SECRET_ACCESS_KEY
    # AWS_SESSION_TOKEN
    aws:
      assume_role:
        role_arn: arn:aws:iam::12345678910:role/my_dev_role
        source_profile: novops

    variables:

      # Secrets Manager
      - name: APP_PASSWORD
        value:
          aws_secret:
            id: dev-app-password

      # SSM Parameter Store
      - name: APP_TOKEN
        value:
          aws_ssm_parameter:
            name: dev-app-token

Google Cloud Secret Manager

Load secrets from Google Cloud Secret Manager. See Google Cloud module reference

environments:
  dev:
    variables:

      # Secret Manager
      - name: APP_PASSWORD
        value:
          gcloud_secret:
            name: projects/my-project/secrets/AppPasswordDev/versions/latest

Azure Key Vault

Load secrets from Azure Key Vault. See Azure Key Vault module reference

environments:
  dev:
    variables:

      # Key Vault
      - name: APP_PASSWORD
        value:
          azure_keyvault_secret:
            vault: vault-dev
            name: app-password

SOPS

Load secrets from SOPS encrypted files. See SOPS module reference

environments: 
  dev:
    variables:

      # SOPS nested key
      - name: APP_PASSWORD
        value:
          sops:
            file: sops/dev/encrypted.yml
            extract: '["app"]["password"]'
    
    # Entire SOPS file as dotenv
    sops_dotenv:
      - file: sops/dev/encrypted-dotenv.yml
      - file: sops/dev/another-encrypted-dotenv.yml

BitWarden

Load secrets from BitWarden. See BitWarden module reference

environments:
  dev:
    variables: 
      
      # BitWarden secret item
      - name: APP_PASSWORD
        value:
          bitwarden:
            entry: "App Password - Dev"
            field: login.password

Examples

Example .novops.yml for an application with database and two environments, dev & prod:

environments:
  # DB login, password and host for dev
  # Pass password as env var
  dev:
    variables:
      - name: DB_PASSWORD
        value:
          hvault_kv2:
            path: app/dev
            key: db_password
      
      - name: DB_USER
        value: postgres

      - name: DB_HOST
        value: db.dev.example.com

  # DB login, password and host for prod
  # Pass password as secure file
  prod:

    files:
      # Password will be saved in a secure file
      # Environment variable DB_PASSWORD_FILE will point to it
      # Such as DB_PASSWORD_FILE=/run/...
      - variable: DB_PASSWORD_FILE
        content:
          hvault_kv2:
            path: app/prod
            key: db_password

    variables:      
      - name: DB_USER
        value: postgres

      - name: DB_HOST
        value: db.prod.example.com

With Novops you can:

Run a sub-command with secrets

Run your deployment script with Database secrets

novops run -- ./deploy-app.sh

# You can run any command
#
# novops run -- ansible-playbook deploy.yml
# novops run -- terraform plan && terraform apply
# novops run -- pulumi up -yrf

Or directly run a sub-shell with secrets loaded:

novops run --sh

Load secrets into your shell

novops load loads secrets directly as dotenv exportable file.

source <(novops load)

Note: for security, Novops won't output anything directly in a terminal to prevent secret from being exposed directly.

Manage multiple environments

By default Novops will prompt for environment

novops run -- ./deploy-app.sh
# Select environment: dev, prod

You can specify environment directly with -e ENV

novops run -e dev -- ./deploy-app.sh

🐳 Docker & Podman

Load environment variables directly into containers:

docker run -it --env-file <(novops load -f dotenv -e dev) alpine sh
podman run -it --env-file <(novops load -f dotenv -e dev) alpine sh

More examples: Ansible, Terraform, Pulumi, GitLab, GitHub and more !

Full Documentation

Checkout full documentation

Community and Support

A question? A problem? A bug to report?

Roadmap

The following modules are expected to be implemented:

Feel free to create an issue and contribute a PR !

Contributing

We welcome contributions: bug reports/fixes, modules, proposals... :) To get started you can check Novops internal architecture and:

Inspiration and similar tools

License

GNU Lesser General Public License

Acknowledgment

Novops was initially developed and used at Novadiscovery who graciously transferred code ownership. Thanks Nova's team for your help in designing and developing Novops.