Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vault-env: Support JWT-based auth methods outside of K8s clusters #1321

Merged

Conversation

gw0
Copy link
Contributor

@gw0 gw0 commented May 10, 2021

Q A
Bug fix? maybe
New feature? yes
API breaks? no
Deprecations? no
Related tickets none
License Apache 2.0

What's in this PR?

This PR enables vault-env to use JWT-based authentication methods while running outside a Kubernetes cluster (and even from outside cloud providers). It just removes an unnecessary check for running in an Kubernetes environment, that made it impossible to use vault-env elsewhere.

Why?

Attempts to use a self-signed GCP SA JWT token (not signed by the metadata server as with gcp-iam) with VAULT_AUTH_METHOD=jwt resulted in:

FATA[0000] failed to create vault clientunable to load in-cluster configuration, KUBERNETES_SERVICE_HOST and KUBERNETES_SERVICE_PORT must be defined  app=vault-env

With this PR you can do:

$ export VAULT_AUTH_METHOD=jwt VAULT_JWT_FILE=/tmp/gcp-jwt.token VAULT_PATH=gcp VAULT_ROLE=mygcprole
$ gcp_create_jwt_token "${GOOGLE_APPLICATION_CREDENTIALS}" "vault/${VAULT_ROLE}" $((15*60)) > "${VAULT_JWT_FILE}"
$ vault-env ./yourcommand
INFO[0001] received new Vault token                      app=vault-env
INFO[0001] initial Vault token arrived                   app=vault-env
INFO[0001] spawning process: [./yourcommand]  app=vault-env

Additional context

To use the above, download the GCP SA private key JSON file (set path in GOOGLE_APPLICATION_CREDENTIALS) and use the following Bash function (roughly based on https://gist.github.com/jtbonhomme/d41efed3946a400bf5f93d7ccad4283c):

base64var() {
    printf "$1" | base64stream
}
base64stream() {
    base64 | tr '/+' '_-' | tr -d '=\n'
}
gcp_create_jwt_token() {
    # Creates a GCP locally-signed JWT token using GCP SA private key.
    key_json_file="$1"
    scope="$2"
    valid_for_sec="${3:-3600}"

    private_key_id=$(jq -r .private_key_id $key_json_file)
    private_key=$(jq -r .private_key $key_json_file)
    sa_email=$(jq -r .client_email $key_json_file)

    header=$(jq -c . <<-EOF
    {
        "alg": "RS256",
        "typ": "JWT",
        "kid": "$private_key_id"
    }
EOF
    )
    claim=$(jq -c . <<-EOF
    {
        "sub": "$sa_email",
        "aud": "$scope",
        "exp": $(($(date +%s) + $valid_for_sec)),
        "iat": $(date +%s)
    }
EOF
    )
    request_body="$(base64var "$header").$(base64var "$claim")"
    signature=$(openssl dgst -sha256 -sign <(echo "$private_key") <(printf "$request_body") | base64stream)

    printf "$request_body.$signature"
}

Because the JWT token creation is independent of the GCP metadata server, this also works outside GCP.

Checklist

  • Code meets the Developer Guide
  • User guide and development docs updated (if needed)

@bonifaido bonifaido self-assigned this May 11, 2021
Copy link
Member

@bonifaido bonifaido left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I think we left this unintentionally, after a refactoring (the values was used previously and now it was ignored).

@bonifaido bonifaido merged commit 505270f into bank-vaults:master May 11, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants