jhaals / ansible-vault

ansible lookup plugin for secrets stored in Vault(by HashiCorp)
BSD 3-Clause "New" or "Revised" License
347 stars 65 forks source link

Multipart Dynamic secrets are not cached in Playbooks #68

Open BenCoffeed opened 6 years ago

BenCoffeed commented 6 years ago

Description

When using a dynamic secret backend that has multi-key values, such as the AWS secret backend which contains access_key and secret_key keys, the lookup plugin gets executed independently when referencing each key. This behavior is not seen when using templates, since Ansible is calling the template engine during the play and the {{ set behavior DOES cache the results. Since the lookup plugin is called again, you cannot simply set a multi-key variable without getting mis-matched secrets.

How to repeat

consider the playbook:

---
- name: create standalone sandbox of rwell applications
  hosts: localhost

  vars:
    aws_creds: "{{ lookup('vault', 'aws/creds/common_get_s3_build') }}"

  tasks:
    - debug:
        var: aws_creds

    - debug:
        var: aws_creds.access_key

    - debug:
        var: aws_creds.secret_key

Expected results:

ok: [localhost] => {
    "aws_creds": {
        "access_key": "A",
        "secret_key": "AA",
        "security_token": null
    }
}
ok: [localhost] => {
    "aws_creds.access_key": "A"
}
ok: [localhost] => {
    "aws_creds.secret_key": "AA"
}

Actual results

ok: [localhost] => {
    "aws_creds": {
        "access_key": "A",
        "secret_key": "AA",
        "security_token": null
    }
}
ok: [localhost] => {
    "aws_creds.access_key": "B"
}
ok: [localhost] => {
    "aws_creds.secret_key": "CC"
}

NOTE: Access keys replaced by single-character identifiers. Secret keys replaced by double-character identifiers matching corresponding access_key identifier.

BenCoffeed commented 6 years ago

Also, to emphasize impact, This also holds true with the playbook:

- name: download artifacts
  aws_s3:
    mode: get
    bucket: artifact-bucket
    object: artifacts.tar.gz
    dest: /tmp/artifacts.tar.gz
    overwrite: different
    aws_access_key: "{{ item.access_key }}"
    aws_secret_key: "{{ item.secret_key }}"
  register: artifacts
  with_vault:
    - aws/creds/common_get_s3_artifacts

Expected Results

Download succeeds

Actual Results

TASK [playbook : download artifacts] ************************************
An exception occurred during task execution. To see the full traceback, use -vvv. The error was: ClientError: An error occurred (403) when calling the HeadBucket operation: Forbidden
failed: [localhost] (item={u'access_key': u'A', u'secret_key': u'BB', u'security_token': None}) => {"changed": false, "error": {"code": "403", "message": "Forbidden"}, "item": {"access_key": "A", "secret_key": "BB", "security_token": null}, "msg": "Failed while looking up bucket (during bucket_check) artifact-check.", "response_metadata": {"host_id": "AKKKDHHTHAGHGHDHEG@G222222222224455=", "http_headers": {"content-type": "application/xml", "date": "Thu, 22 Feb 2018 16:20:20 GMT", "server": "AmazonS3", "transfer-encoding": "chunked", "x-amz-bucket-region": "us-east-1", "x-amz-id-2": "gAAAAAA+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=", "x-amz-request-id": "AAAAAAAAAAAAA"}, "http_status_code": 403, "request_id": "AAAAAAAAAAAAAAA", "retry_attempts": 1}}

NOTE: Access keys replaced by single-character identifiers. Secret keys replaced by double-character identifiers matching corresponding access_key identifier.