---
title: ConcourseのCredential ManagementにCredHubを使う(ACL対応)
tags: ["Concourse CI", "CredHub", "UAA", "BOSH", "Cloud Foundry"]
categories: ["Dev", "CI", "ConcourseCI"]
date: 2017-12-18T17:59:48Z
updated: 2017-12-20T10:32:06Z
---

ConcourseでCredHubを使ってCredentials管理する方法を紹介します。

<!-- toc -->

### 普通のCredentials設定

Concourseのパイプラインで使用するCredentialsは、通常バージョン管理しないようにパイプラインから外出しし、`-l credentials.yml`で埋め込みます。


次の例を見てみます。

``` yaml
# hello.yml
jobs:
- name: hello-world
  plan:
  - task: say-hello
    config:
      platform: linux
      image_resource:
        type: docker-image
        source:
          repository: ubuntu
      params:
        MY_SECRET: ((my-secret))
      run:
        path: bash
        args:
        - -c
        - |
          set -e
          echo "MY_SECRET=${MY_SECRET}"
```

`((my-secret))`は次の`credentials.yml`で管理されます。

``` yaml
# credentials.yml
my-secret: P@$$w0rd
```

`-l`で設定します。


```
fly -t main sp -p hello -c hello.yml -l creds.yml 
```

unpauseして実行してみます。

```
fly -t main up -p hello
fly -t main tj -j hello/hello-world --watch
```

実行結果は

```
started hello/hello-world #1

initializing
running bash -c set -e
echo "MY_SECRET=${MY_SECRET}"

MY_SECRET=P@$$w0rd
```

となります。

> 注意:
> 
> ビルドログは残るので、この例のようにCredentialsを出力するのは避けてください!

一見問題なさそうですが、実はこのやり方だとCredentialsが組み込まれた状態でパイプラインがDBに保存されます。
なので、`fly get-pipeline`でCredentialsが丸見えです。

```
$ fly -t main gp -p hello
groups: []
resources: []
resource_types: []
jobs:
- name: hello-world
  plan:
  - task: say-hello
    config:
      platform: linux
      image_resource:
        type: docker-image
        source:
          repository: ubuntu
      params:
        MY_SECRET: P@$$w0rd
      run:
        path: bash
        args:
        - -c
        - |
          set -e
          echo "MY_SECRET=${MY_SECRET}"
```

例えば複数ユーザーでConcourseチームを共有している場合、個人のパスワードなどをパイプラインに埋め込んでしまうと、同チームの他のユーザーに見えてしまいます。

このやり方でCredentialsを使用する場合は、チームで共有のBotアカウントなどを作成し、そちらを`credentials.yml`に記述する必要があります。


### ConcourseのCredentials Management

本当の意味でのCredentials管理には`-l`は明らかに不適切です。Concourseでは外部のCredentialsサーバーと連携するCredentials Managementの仕組みが用意されています。

http://concourse.ci/creds.html

次の項目に設定されている`((param))`を適切に管理できるようになります。

> * `source` under `resources` in a pipeline
> * `source` under `resource_types` in a pipeline
> * `source` under `image_resource` in a task config
> * `params` in a pipeline
> * `params` in a task config

サポートされているCredentialsサーバーは

* [Vault](https://vaultproject.io/)
* [CredHub](https://github.com/cloudfoundry-incubator/credhub)

です。

Vaultはとても有名なプロダクトなので、すでにVaultを利用している方はこちらを選択すれば良いと思います。
CredHubはVaultに比べるとマイナーです。CredHubはCloud Foundry Foundationで開発されおり、BOSHやCloud FoundryのService BrokerのCredentials管理用途で開発されています。
UAAと連携できるなど、Cloud FoundryユーザーにはCredHubの方が馴染みがあるでしょう。

Vaultは機能豊富ですが、ConcourseのCredentials管理のみのために使うにはtoo muchなのと、Storage Backendとしてofficialにサポートされているのが、Consul、Filesystem、In-Memoryだけなので、
PostgreSQL、MySQLが使えるCredHubの方が手軽感があります。

以降ではCredHubとの連携について説明します。

> CredHubのサポートはConcourse 3.5.0以降です。

### CredHub連携の設定

設定方法はドキュメントに記述されています。

http://concourse.ci/creds.html#credhub

Concourseの起動時にATC側にCredHubの接続情報を設定する必要があります。

BOSHを使ったデプロイ方法を紹介します。ここではBOSH Director(CredHub + UAA設定済み)がデプロイ済みであることを前提とします。

まずは、CredHubなしのConcourseデプロイから始めます。

> 本線から外れますが、Concourse 3.6.0から[concourse-deployment](https://github.com/concourse/concourse-deployment)というBOSH manifest + ops-files (YAML差分ファイル)を管理するレポジトリができました。
これまでのようにドキュメントのサンプルマニフェストをコピペして環境に合わせて修正+バージョンアップの度に差分適用ということはしなくて良くなります。
>
> concourse-deploymentにはBOSH Directorを使用したcluster版とDirector不要のSingle VMを作成するlite版が用意されています。
> ここではcluster版を使用し、BOSH Directorが既に存在することを前提とします。以下の説明はBOSH DirectorにUAA + CredHubが設定されている環境(BOSH Lite)で試しています。


README通りの最小構成インストールを行います。

``` bash
git clone git@github.com:concourse/concourse-deployment.git
# 執筆時点で　302bbbc556a54716338a5133949b514976a84515
bosh deploy -d concourse concourse-deployment/cluster/concourse.yml \
  -l concourse-deployment/versions.yml \
  -o concourse-deployment/cluster/operations/static-web.yml \
  -o concourse-deployment/cluster/operations/no-auth.yml \
  --var web_ip=10.244.0.120 \
  --var external_url=http://10.244.0.120:8080 \
  --var network_name=default \
  --var web_vm_type=default \
  --var db_vm_type=default \
  --var db_persistent_disk_type=default \
  --var worker_vm_type=default \
  --var deployment_name=concourse
# デモ用の認証なし設定です
```

まずは次の状態ができています。

```
$ bosh -d concourse vms
Using environment '192.168.50.6' as client 'admin'

Task 43189. Done

Deployment 'concourse'

Instance                                     Process State  AZ  IPs           VM CID                                VM Type  
db/9ec9a39f-f2a0-4e77-98be-013e02ba65dc      running        z1  10.244.0.131  2230d55b-c916-4c24-5b28-0c70e96033a5  default  
web/9a84ace9-7e15-461e-b5cc-0828c090f33b     running        z1  10.244.0.120  902a5998-4102-4ed3-4ccb-57d98a918f37  default  
worker/d17466e1-6552-474f-9361-f09ba68f08a2  running        z1  10.244.0.143  98890a0d-dcba-49c7-4891-e7b8a1a86711  default  

3 vms

Succeeded
```

![image](https://user-images.githubusercontent.com/106908/34139691-7e3a2860-e4b9-11e7-93ef-c763cd0e9837.png)


次にCredHubを設定します。ここではCredHubと**既存の**UAAを連携させます。
今回はCredHubをデプロイをConcourseと同じdeploymentの中に新規でデプロイします。バックエンドにはPostgreSQLを使用し、Concourse用のDBに相乗りします。

すなわち、次のような構成になります。

![image](https://user-images.githubusercontent.com/106908/34141390-3b0eba50-e4c4-11e7-9cdf-fcc17b347d0e.png)

UAAも一緒にBOSHでデプロイできますが、
既存のUAA(Cloud Foundry Application Runtime内に存在)と連携するのが一番想定される利用シーンなので。UAAも一緒にデプロイする方法はまたいつか。

* CredHubのBOSH Releaseは[pivotal-cf/credhub-release](https://github.com/pivotal-cf/credhub-release)です。
* atcのCredHub連携の設定情報は[こちら](https://github.com/concourse/concourse/blob/v3.8.0/jobs/atc/spec#L486-L509)です。

#### UAAクライアントの登録

ここで、まずはatcをUAAのOAuth2クライアントとしてClient Credentials Grant Typeで登録する必要があります。
UAAのclientでauthoritiesに`uaa.admin`を持つclient(下の例では`uaa_admin`)のtokenを使い、`uaac`コマンドで新規にclientを登録します。

```
uaac target https://(UAAのIP):(UAAのHTTPS Port) --skip-ssl-validation
uaac token client get uaa_admin -s (uaa_adminのclient secret)
```

> PCFのERT(PAS)のUAAを使う場合は、client名は`admin`でClient SecretはOps ManagerのERT(PAS) TileのCredentialsタブの"Admin Client Credentials"から取得できます。

`atc_to_credhub`という名前のクライアントを登録します。
UAAクライアントがCredHubリソースにアクセスするためには`credhub.write`と`credhub.read`authoritiesが必要です。

```
uaac client add atc_to_credhub \
     --name atc_to_credhub \
     --secret (atc_to_credhubのclient secret) \
     --authorized_grant_types client_credentials \
     --authorities credhub.write,credhub.read \
     --access_token_validity 3600
```

client secretは適当な値を指定してください。


#### CredHubを有効にするops-fileの作成

CredHubのデプロイとatcにCredHubを設定するops-file (`ops-files/concourse-credhub.yml`) を作成します。

```yml
- type: replace
  path: /releases/-
  value:
    name: credhub
    url: https://bosh.io/d/github.com/pivotal-cf/credhub-release?v=1.6.5
    version: 1.6.5
    sha1: eda4e8873aa2dbfacb1857b175f761d2d0b64538

- type: replace
  path: /instance_groups/name=web/jobs/name=atc/properties/credhub?
  value:
    url: ((credhub_url))
    tls:
      insecure_skip_verify: true
      ca_cert: ((default-ca))
    client_id: ((credhub_client_id))
    client_secret: ((credhub_client_secret))

- type: replace
  path: /instance_groups/name=web:before
  value:
    name: credhub
    instances: 1
    vm_type: default
    azs: [z1]
    stemcell: trusty
    networks:
    - name: default
      static_ips: [((credhub_ip))]

    jobs:
    - name: credhub
      release: credhub
      properties:
        credhub:
          tls: ((credhub-tls))
          authentication:
            uaa:
              url: ((uaa-url))
              verification_key: ((uaa-jwt.public_key))
              ca_certs:
              - ((uaa-tls.ca)) 
          data_storage:
            type: postgres
            username: credhub
            password: ((credhub-db-password))
            host: ((postgres-ip))
            port: 5432
            database: credhub
            require_tls: false
          encryption:
            keys: 
            - provider_name: int
              encryption_password: ((credhub-encryption-password))
              active: true
            providers: 
            - name: int
              type: internal

- type: replace
  path: /instance_groups/name=db/networks/0/static_ips?
  value: [((postgres-ip))]

- type: replace
  path: /instance_groups/name=db/jobs/name=postgres/properties/databases/databases/-
  value:
    name: credhub

- type: replace
  path: /instance_groups/name=db/jobs/name=postgres/properties/databases/roles/-
  value: 
    name: credhub
    password: ((credhub-db-password))

- type: replace
  path: /variables/-
  value:
    name: default-ca
    type: certificate
    options:
      is_ca: true
      common_name: ca

- type: replace
  path: /variables/-
  value:
    name: credhub-tls
    type: certificate
    options:
      ca: default-ca
      common_name: ((credhub-ip))
      alternative_names:
      - ((credhub-ip))
      - 127.0.0.1

- type: replace
  path: /variables/-
  value:
    name: credhub-db-password
    type: password

- type: replace
  path: /variables/-
  value:
    name: credhub-encryption-password
    type: password
    options:
      length: 40
```

> AWSで作成する場合は、CredHubの`vm_type`を`t2.medium`以上にしてください。

このops fileを組み込んで、再度`bosh deploy`します。

```
bosh deploy -d concourse concourse-deployment/cluster/concourse.yml \
  -l concourse-deployment/versions.yml \
  -o concourse-deployment/cluster/operations/static-web.yml \
  -o concourse-deployment/cluster/operations/no-auth.yml \
  -o ops-files/concourse-credhub.yml \
  --var web_ip=10.244.0.120 \
  --var external_url=http://10.244.0.120:8080 \
  --var network_name=default \
  --var web_vm_type=default \
  --var db_vm_type=default \
  --var db_persistent_disk_type=default \
  --var worker_vm_type=default \
  --var postgres-ip=10.244.0.124 \
  --var credhub_url=https://10.244.0.125:8844 \
  --var credhub-ip=10.244.0.125 \
  --var uaa-url=https://(UAAのIP):(UAAのHTTPS Port) \
  --var-file uaa-tls.ca=(UAAのCA証明書pemファイルパス) \
  --var-file uaa-jwt.public_key=(UAAのJWTの署名キーのpemファイルパス) \
  --var credhub_client_id=atc_to_credhub \
  --var credhub_client_secret=(atc_to_credhubのclient secret) \
  --var deployment_name=concourse \
  --no-redact
```

> UAAのJWTの署名キーは`https://(UAAのIP):(UAAのHTTPS Port)/token_keys`から取得可能です。
>
> ```
> curl -s -k https://(UAAのIP):(UAAのHTTPS Port)/token_keys | jq -r .keys[0].value > jwt-sign-key.pem
> ```

デプロイできると、次のようにcredhubインスタンスが立ち上がっているのがわかります。

```
$ bosh -d concourse vms
Using environment '192.168.50.6' as client 'admin'

Task 43204. Done

Deployment 'concourse'

Instance                                      Process State  AZ  IPs           VM CID                                VM Type  
credhub/7f9d897a-afd0-4acf-a103-a88c97f7fd32  running        z1  10.244.0.125  cc065ca8-fb74-4b7c-43d2-df088edca871  default  
db/9ec9a39f-f2a0-4e77-98be-013e02ba65dc       running        z1  10.244.0.124  214fd1fe-0193-4566-7c9f-3abca01beb94  default  
web/9a84ace9-7e15-461e-b5cc-0828c090f33b      running        z1  10.244.0.120  902a5998-4102-4ed3-4ccb-57d98a918f37  default  
worker/d17466e1-6552-474f-9361-f09ba68f08a2   running        z1  10.244.0.143  98890a0d-dcba-49c7-4891-e7b8a1a86711  default  
```

これでConcourseとCredHubの連携ができました。

```
fly -t main login -c http://10.244.0.120:8080
```

でログインします。

#### CredHubからパイプラインのCredentials取得

いよいよConcourseからCredHubにアクセスします。

まずは、冒頭の`hello.yml`を`-l`なしでセットし、ジョブを実行します。

```
fly -t main sp -p hello -c hello.yml
fly -t main up -p hello
fly -t main tj -j hello/hello-world --watch
```

結果は次のようになるでしょう。


```
$ fly -t main tj -j hello/hello-world --watch
started hello/hello-world #1

initializing
Expected to find variables: my-secret
errored
```

`my-secret`を設定していないので当然エラーです。

この`my-secret`をCredHubに登録しましょう。

[`credhub`](https://github.com/cloudfoundry-incubator/credhub-cli)コマンドを使用します。
credhubに`atc_to_credhub`のClient Credentialsでログインします。

```
credhub login -s 10.244.0.125:8844 --skip-tls-validation --client-name atc_to_credhub --client-secret (atc_to_credhubのclient secret)
```

> `--skip-tls-validation`は非推奨で、`--ca-cert=(UAAのCA証明書)  --ca-cert=(CredHubのCA証明書)`を設定するのが推奨です。

`credhub find`を実行すると登録されているCredentials一覧が見れます。まだ空です。

```
$ credhub find
credentials: []
```

Concourseは

* `/concourse/(team name)/(pipeline name)/(param name)`
* `/concourse/(team name)/(param name)`

のどちらかのCredentialの取得を試みます。上が優先です。
チーム共通のパラメータは下のCredentialsに設定し、パイプライン固有のパラメータは上のCredentialsに設定するのが良いでしょう。

今回の例(`my-secret`)ではチーム共通パラメータとして、次のように設定します。


```
$ credhub generate -t password -n /concourse/main/my-secret
id: 8d2d5fbe-dd20-4e75-b38f-9e103dea0333
name: /concourse/main/my-secret
type: password
value: S9D0reqoZd6NlR1mbsXVVUP3I9Ywtm
version_created_at: 2017-12-19T06:05:57Z
```

これを設定した後、再度ジョブを実行すると、

```
$ fly -t main tj -j hello/hello-world --watch
started hello/hello-world #2

initializing
running bash -c set -e
echo "MY_SECRET=${MY_SECRET}"

MY_SECRET=S9D0reqoZd6NlR1mbsXVVUP3I9Ywtm
succeeded
```

取得できました。


Credentialsをrotateしてみましょう。

```
$ credhub regenerate -n /concourse/main/my-secret
id: db89b907-cf35-4fd8-b9d6-66a32f868726
name: /concourse/main/my-secret
type: password
value: Nzcw4hnE5ObHIZH3YGqgs1ILzwzvqu
version_created_at: 2017-12-19T06:08:58Z
```

再度ジョブを実行すると、

```
$ fly -t main tj -j hello/hello-world --watch
started hello/hello-world #3

initializing
running bash -c set -e
echo "MY_SECRET=${MY_SECRET}"

MY_SECRET=Nzcw4hnE5ObHIZH3YGqgs1ILzwzvqu
succeeded
```

rotateされた値が反映されました。

これでConcourseのパイプラインとCredentialsを分けることができました。

これで大体良さそうなのですが、まだ課題が残っています。
今回はCredHubにログインするのに`atc_to_credhub`クライアントのClient Credentialを使いました。
みんながこのClient Credentialを共有すると、このCredHubにアクセスできる人全員がCredentialsを参照可能になり、
元の問題を根本的には解決していません。

ここでCredHubのACL機能を使用します。

### CredHubのACL

CredHubのACL機能はPhase1という開発状況ですが、一応今回の用途には利用可能でした。

https://github.com/cloudfoundry-incubator/credhub/blob/master/docs/authorization-phase1.md

この機能を使うと各Credentialに対して、

* UAAクライアント (atcに相当)
* UAAユーザー (concourseを使うユーザーに相当)

というActorそれぞれに`read`や`write`と言ったpermissionを設定可能です。

この2つActorを使い分けます。

次の図のようにConcourse(atc)からは`atc_to_credhub`のClient Credentialsでアクセスし、ConcourseユーザーはResource Owner Passwordでアクセスするようにします。

![image](https://user-images.githubusercontent.com/106908/34148020-126cfa84-e4e3-11e7-8636-e497a890e1a8.png)

各パイプラインのCredentialsはResource Owner Passwordで登録することにより、自分が設定したCredentialsは他のユーザーからは参照されなくなります。
また、各Credentialに対して`atc_to_credhub`からの`read`を許可することでConcourseタスクからCredentialを参照可能になります。

このACL機能を有効にするには`credhub` jobの`properties`に[`credhub.authorization.acls.enabled`](https://github.com/pivotal-cf/credhub-release/blob/1.6.5/jobs/credhub/spec#L167-L169)を`true`にする必要があります。

このpropertyを設定するops file(`ops-files/credhub-enable-acl.yml`)を次のように作成します。


``` yaml
- type: replace
  path: /instance_groups/name=credhub/jobs/name=credhub/properties/credhub/authorization?/acls?/enabled?
  value: true
```

これを組み込んで再度`bosh deploy`

```
bosh deploy -d concourse concourse-deployment/cluster/concourse.yml \
  -l concourse-deployment/versions.yml \
  -o concourse-deployment/cluster/operations/static-web.yml \
  -o concourse-deployment/cluster/operations/no-auth.yml \
  -o ops-files/concourse-credhub.yml \
  -o ops-files/credhub-enable-acl.yml \
  --var web_ip=10.244.0.120 \
  --var external_url=http://10.244.0.120:8080 \
  --var network_name=default \
  --var web_vm_type=default \
  --var db_vm_type=default \
  --var db_persistent_disk_type=default \
  --var worker_vm_type=default \
  --var postgres-ip=10.244.0.124 \
  --var credhub_url=https://10.244.0.125:8844 \
  --var credhub-ip=10.244.0.125 \
  --var uaa-url=https://(UAAのIP):(UAAのHTTPS Port) \
  --var-file uaa-tls.ca=(UAAのCA証明書pemファイルパス) \
  --var-file uaa-jwt.public_key=(UAAのJWTの署名キーのpemファイルパス) \
  --var credhub_client_id=atc_to_credhub \
  --var credhub_client_secret=(atc_to_credhubのclient secret) \
  --var deployment_name=concourse \
  --no-redact
```

いったん、`/concourse/main/my-secret`を削除しておきます。

```
$ credhub delete -n /concourse/main/my-secret
Credential successfully deleted
```

#### UAAユーザー作成

`uaac user add`コマンドでUAAユーザーを作成します。`credhub.read`と`credhub.write`のGroupに所属する必要があります。

`demo1`と`demo2`というユーザーを作成します。

```
# credhub.read, credhub.writeグループが存在しない場合は作成
uaac group add credhub.read
uaac group add credhub.write

# demo1ユーザーの作成及び、credhub.read/credhub.writeグループの設定
uaac user add demo1 --password demo1 --email demo1@example.com
uaac member add credhub.read demo1
uaac member add credhub.write demo1

# demo2ユーザーの作成及び、credhub.read/credhub.writeグループの設定
uaac user add demo2 --password demo2 --email demo2@example.com
uaac member add credhub.read demo2
uaac member add credhub.write demo2
```

> CFのUAAを使う場合は、cfユーザーがUAAに登録されているので、`uaac member add`をすれば良いです。

> UAAに`credhub_cli`というクライアントがいない場合は次のコマンドで作成してください
> 
> ```
> uaac client add credhub_cli \
> --name credhub_cli \
> --secret "" \
> --authorized_grant_types password,refresh_token \
> --scope credhub.write,credhub.read \
> --access_token_validity 3600 \
> --refresh_token_validity 36000
> ```
>
> [bosh-deployment](https://github.com/cloudfoundry/bosh-deployment)でBOSH+UAA+CredHub構成を作成している場合は、`credhub_cli`クライアントは作成済みです。
> 
> https://github.com/cloudfoundry/bosh-deployment/blob/218e6d5030d89ca9f31c50b8b308e2a78d2a0997/credhub.yml#L68-L77

#### UAAユーザーでCredential作成

先ほどは`atc_to_credhub`クライアントのClient Credentialでログインしましたけど、
今回はUAAユーザーのResource Owner Passwordでログインします。


```
credhub login -s 10.244.0.125:8844 --skip-tls-validation --username demo1 --password demo1
```

`client-name`/`client-secret`ではなく`username`/`password`を指定します。

`demo1`のResource Owner Passwordで`/concourse/main/my-secret`を作成します。

```
$ credhub generate -t password -n /concourse/main/my-secret
id: 70eeef24-9588-4c79-b32c-1dfaead55130
name: /concourse/main/my-secret
type: password
value: NNAlffTHs16HLe5IErwZ3LEOlK2X4i
version_created_at: 2017-12-19T10:05:59Z
```

この状態で、タスクを実行すると、


```
$ fly -t main tj -j hello/hello-world --watch
started hello/hello-world #4

initializing
Expected to find variables: my-secret
errored
```

エラーになります。エラーメッセージがわかりにくいですが、
`atc_to_credhub`の権限で`/concourse/main/my-secret`にアクセスできないため、Credentialが見つかりませんでした。

#### Permissionの追加

ACLは[Permission API](https://credhub-api.cfapps.io/#permissions)で設定可能です。
CredHub CLI 1.5.1ではサブコマンドとして用意されていないので、`curl`で直接REST APIを叩く必要があります...

まずは`/concourse/main/my-secret`のPermissionを確認します。

```
$ curl -k -H "Authorization: $(credhub --token)" $(credhub api)/api/v1/permissions?credential_name=/concourse/main/my-secret
{"credential_name":"/concourse/main/my-secret","permissions":[{"actor":"uaa-user:0d9c6701-c3df-4c2e-936c-8c48e551e764","operations":["read","write","delete","read_acl","write_acl"]}]}
```

整形すると

``` json
{
  "credential_name": "/concourse/main/my-secret",
  "permissions": [
    {
      "actor": "uaa-user:0d9c6701-c3df-4c2e-936c-8c48e551e764",
      "operations": [
        "read",
        "write",
        "delete",
        "read_acl",
        "write_acl"
      ]
    }
  ]
}
```

です。

> 余談ですが、`actor`の部分は`uaa-user:(UAA TokenのJWTのuser_id)`です。
>
> tokenは`credhub --token`の結果を[https://jwt.io](https://jwt.io)に貼り付ければ確認できます。
>
> ![image](https://user-images.githubusercontent.com/106908/34152339-96565a9e-e4f1-11e7-894c-50dfa7ab8279.png)

ここに`atc_to_credhub`クライアントがアクセスできるように設定します。UAAクライアントの場合、`actor`には`uaa-client:(Client ID)`を設定します。


```
curl -k -v -H "Authorization: $(credhub --token)" $(credhub api)/api/v1/permissions?credential_name=/concourse/main/my-secret \
     -H "Content-Type: application/json" \
     -d '{
      "credential_name": "/concourse/main/my-secret",
      "permissions": [
      {
        "actor": "uaa-client:atc_to_credhub",
        "operations": ["read"]
      }]
     }'
```

再度、`/concourse/main/my-secret`のPermissionを確認します。

```
$ curl -s -k -H "Authorization: $(credhub --token)" $(credhub api)/api/v1/permissions?credential_name=/concourse/main/my-secret | jq .
{
  "credential_name": "/concourse/main/my-secret",
  "permissions": [
    {
      "actor": "uaa-user:0d9c6701-c3df-4c2e-936c-8c48e551e764",
      "operations": [
        "read",
        "write",
        "delete",
        "read_acl",
        "write_acl"
      ]
    },
    {
      "actor": "uaa-client:atc_to_credhub",
      "operations": [
        "read"
      ]
    }
  ]
}
```

この状態で再度タスクを実行すると、

```
$ fly -t main tj -j hello/hello-world --watch
started hello/hello-world #5

initializing
running bash -c set -e
echo "MY_SECRET=${MY_SECRET}"

MY_SECRET=NNAlffTHs16HLe5IErwZ3LEOlK2X4i
succeeded
```

Credentialにアクセスできました!


ではユーザー`demo2`に切り替えてみます。

```
credhub login -s 10.244.0.125:8844 --skip-tls-validation --username demo2 --password demo2
```

このユーザーで`/concourse/main/my-secret`にアクセスすると

```
$ credhub get -n /concourse/main/my-secret
The request could not be completed because the credential does not exist or you do not have sufficient authorization.
```

権限エラーになりました。

これで無事にACLの設定ができました。

### まとめ

* ConcourseのCredentials Managementを説明しました
* BOSHでConcourse + CredHubをデプロイする方法を説明しました
* CredHubでACLを設定する方法を説明しました
