Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/tcdowney/cred_hubble
Unofficial Ruby Client for Cloud Foundry CredHub Credential Store ðŸ”
https://github.com/tcdowney/cred_hubble
cloud-foundry-credhub credub-ruby-client http-client ruby
Last synced: 2 months ago
JSON representation
Unofficial Ruby Client for Cloud Foundry CredHub Credential Store ðŸ”
- Host: GitHub
- URL: https://github.com/tcdowney/cred_hubble
- Owner: tcdowney
- License: mit
- Created: 2017-09-25T02:53:49.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2017-11-03T02:40:40.000Z (about 7 years ago)
- Last Synced: 2024-04-26T19:22:24.231Z (9 months ago)
- Topics: cloud-foundry-credhub, credub-ruby-client, http-client, ruby
- Language: Ruby
- Homepage: http://www.rubydoc.info/gems/cred_hubble/CredHubble/Client
- Size: 65.4 KB
- Stars: 2
- Watchers: 2
- Forks: 1
- Open Issues: 1
-
Metadata Files:
- Readme: README.md
- License: LICENSE.txt
Awesome Lists containing this project
README
# CredHubble :full_moon_with_face::telescope::full_moon_with_face:
[![Gem Version](https://badge.fury.io/rb/cred_hubble.svg)](https://badge.fury.io/rb/cred_hubble) [![Build Status](https://travis-ci.org/tcdowney/cred_hubble.svg?branch=master)](https://travis-ci.org/tcdowney/cred_hubble)
Unofficial Ruby client for storing and fetching credentials from a [Cloud Foundry CredHub](https://github.com/cloudfoundry-incubator/credhub) credential store.
The goal of this gem is to make it easier for Ruby apps (Rails, Sinatra, etc.) deployed on Cloud Foundry to store and retrieve secrets (e.g. Rails session_token_base, database credentials, AWS keys, etc.).
For a more concrete example of usage, I've written a blog post on how one might [use CredHubble with a Rails app](https://downey.io/blog/securing-rails-credentials-cloud-foundry-credhub/).CredHubble is just something I work on in my spare time for fun and is not feature-complete, but it should get the job mostly done.
If you do end up using it and find any bugs or would like to see more functionality, feel free to [submit a PR](https://github.com/tcdowney/cred_hubble/pulls) or [log an issue](https://github.com/tcdowney/cred_hubble/issues).View the [usage](#usage) section to see what CredHub endpoints the gem currently supports.
## Installation
To install the latest release, add this line to your application's Gemfile:
```ruby
gem 'cred_hubble', '~> 0.1.0'
```And then execute:
$ bundle
Or install it yourself as:
$ gem install cred_hubble
## UsageCredHubble currently supports the following [CredHub endpoints](https://credhub-api.cfapps.io):
* **[Client Creation and Authentication](#client-creation-and-authentication)**
* **[GET Info](#get-info-and-get-health):** `/info`
* **[GET Health](#get-info-and-get-health):** `/health`
* **[GET Encryption Key Usage](#get-encryption-key-usage):** `/api/v1/key-usage`* **[GET Credential by ID](#get-credential-by-id):** `/api/v1/data/`
* **[GET Credentials by Name](#get-credentials-by-name):** `/api/v1/data?name=`
* **[PUT Credential](#put-credential):** `/api/v1/data`
* **[DELETE Credential by Name](#delete-credential-by-name):** `/api/v1/data`
* **[POST Interpolate Credentials](#post-interpolate-credentials):** `/api/v1/interpolate`* **[GET Permissions by Credential Name](#get-permissions-by-credential-name):** `/api/v1/permissions?credential_name=`
* **[POST Add Permissions](#post-add-permissions):** `/api/v1/permissions`
* **[DELETE Delete Permissions](#delete-delete-permissions):** `/api/v1/permissions?credential_name=&actor=`### Client Creation and Authentication
To call endpoints that require authentication, you will need to authenticate with either an oAuth2 bearer token 'Authorization' header or with certificate-based [mutual TLS](https://en.wikipedia.org/wiki/Mutual_authentication) (mTLS).
Here are some examples:#### Authenticating with an oAuth2 header
```ruby
> auth_header = 'eyJhbGc.....OiJSUzI1NiIsI' # omit any 'bearer' portion
> credhub_client = CredHubble::Client.new_from_token_auth(
host: 'credhub.your-cloud-foundry.com',
port: '8844',
auth_header_token: auth_header
)
> credential = credhub_client.credential_by_id('f8d5a201-c3b9-48ae-8bc4-3b86b42210a1')
=> # client_cert_path = '/etc/cf-instance-credentials/instance.crt' # ENV['CF_INSTANCE_CERT']
> client_key_path = '/etc/cf-instance-credentials/instance.key' # ENV['CF_INSTANCE_KEY']
> credhub_client = CredHubble::Client.new_from_mtls_auth(
host: 'credhub.your-cloud-foundry.com',
port: '8844',
client_cert_path: client_cert_path,
client_key_path: client_key_path
)
> credential = credhub_client.credential_by_id('f8d5a201-c3b9-48ae-8bc4-3b86b42210a1')
=> # auth_header = 'eyJhbGc.....OiJSUzI1NiIsI' # omit any 'bearer' portion
> credhub_ca_path = '/some/path/certs/credhub_ca.crt'
> credhub_client = CredHubble::Client.new_from_token_auth(
host: 'credhub.your-cloud-foundry.com',
port: '8844',
auth_header_token: auth_header,
ca_path: credhub_ca_path
)> credential = credhub_client.credential_by_id('f8d5a201-c3b9-48ae-8bc4-3b86b42210a1')
=> # credhub_client = CredHubble::Client.new(host: 'credhub.your-cloud-foundry.com', port: '8844')
> info = credhub_client.info
=> # info.auth_server.url
=> "https://uaa.service.cf.internal:8443"
> health = credhub_client.health
=> # health.status
=> "UP"
```For accessing endpoints that require authentication, simply create an authenticated client using one of the [authentication methods above](#authentication).
### GET Credential by ID
The `credential_by_id` method retrieves a single Credential resource from CredHub by ID.```ruby
> credhub_client.credential_by_id('f297f736-dad2-4450-a7da-d3ff99f2030d')
=> # credentials = credhub_client.credentials_by_name('/admin-user-password')
=> # credentials.count
=> 3
> credentials.map(&:id)
=> ["5298e0e4-c3f5-4c73-a156-9ffce4c137f5", "6980ec59-c7e6-449a-b525-298648cfe6a7", "3e709d6e-585c-4526-ac0d-fe99316f2255"]
> credentials = credhub_client.credentials_by_name('/admin-user-password', versions: 2)
> credentials.count
=> 2
> credentials.map(&:id)
=> ["5298e0e4-c3f5-4c73-a156-9ffce4c137f5", "6980ec59-c7e6-449a-b525-298648cfe6a7"]
> credentials = credhub_client.credentials_by_name('/admin-user-password', current: true)
=> # credentials.count
=> 1
> credentials.map(&:id)
=> ["5298e0e4-c3f5-4c73-a156-9ffce4c137f5"]
```Most times, though, you'll just want to grab the value of the most current version of a credential. This is where the `current_credential_value` method comes in.
Here's what that might look like for the example above:```ruby
> credhub_client.current_credential_value('/admin-user-password')
=> "8mn6LSLzJqhVxnqYCCXUxUADdj8XneYP"
```### PUT Credential
You can create new Credentials using the `put_credential` method. If you wish to replace an already existing Credential, simply pass
`overwrite: true` to the method and CredHub will create a new version of the Credential. Previous versions can be retrieved by using
the `credentials_by_name` method.```ruby
> credential = CredHubble::Resources::UserCredential.new(
name: '/foundry-fred-user',
value: {username: 'foundy_fred', password: 's3cr3t'}
)
=> # credhub_client.put_credential(credential)
=> #,
@id="92775889-71e0-41d1-a44c-93eb8fc5161a",
@type="user",
@version_created_at="2017-10-06T05:10:57Z">
> credential.value.password = 'foo bar'
=> "foo bar"
> credhub_client.put_credential(credential, overwrite: true)
=> #,
@id="292ae24c-d7a3-4d8b-86a2-43630b83bafb",
@type="user",
@version_created_at="2017-10-06T05:11:43Z">
````By default, only the creator of a Credential has access to read, write, delete, view its ACL, or updates its ACL. If you wish to
grant other parties various permissions for a given Credential, the `put_credential` method takes an optional `additional_permissions` array.```ruby
> credential = CredHubble::Resources::UserCredential.new(
name: '/foundry-fred-user',
value: {username: 'foundy_fred', password: 's3cr3t'}
)
=> # permission = CredHubble::Resources::Permission.new(
actor: 'uaa-user:82f8ff1a-fcf8-4221-8d6b-0a1d579b6e47',
operations: ['write', 'read']
)
=> #
> credhub_client.put_credential(credential, additional_permissions: [permission])
=> # credentials = credhub_client.credentials_by_name('/admin-user-password')
=> # credentials.count
=> 3
> credhub_client.delete_credential_by_name('/admin-user-password')
=> true
> credhub_client.credentials_by_name('/admin-user-password')
=> CredHubble::Http::NotFoundError: status: 404, body: {"error":"The request could not be completed ...
````### POST Interpolate Credentials
Cloud Foundry applications traditionally access the credentials for any bound service instances through a `VCAP_SERVICES` environment variable.
Nowadays, however, some Service Brokers are CredHub aware and may choose to store service instance credentials in CredHub.
Apps bound to said services would only see `"credhub-ref"` key in place of actual credentials for that service instance. Here's an example `VCAP_SERVICES`:```json
{
"grid-config":[
{
"credentials":{
"credhub-ref":"/grid-config/users/kflynn"
},
"label":"grid-config",
"name":"config-server",
"plan":"digital-frontier",
"provider":null,
"syslog_drain_url":null,
"tags":[
"configuration",
"biodigital-jazz"
],
"volume_mounts":[]
}
],
"encomSQL":[
{
"credentials":{
"credhub-ref":"/encomSQL/db/users/63f7b900-982f-4f20-9213-6d270c3c58ea"
},
"label":"encom-db",
"name":"encom-enterprise-db",
"plan":"enterprise",
"provider":null,
"syslog_drain_url":null,
"tags":[
"database",
"sql"
],
"volume_mounts":[]
}
]
}
```Fortunately, CredHub supports an "interpolate" endpoint which allows an app to populate these values wholesale.
Here's how a CF application might use CredHubble's `interpolate_credentials` method to do that via mTLS authentication:```ruby
> client_cert_path = ENV['CF_INSTANCE_CERT']
> client_key_path = ENV['CF_INSTANCE_KEY']
> credhub_client = CredHubble::Client.new_from_mtls_auth(
host: 'credhub.your-cloud-foundry.com',
port: '8844',
client_cert_path: client_cert_path,
client_key_path: client_key_path
)
> interpolated_services_json = credhub_client.interpolate_credentials(ENV['VCAP_SERVICES'])
=> '{
"grid-config":[
{
"credentials":{
"username":"kflynn",
"password":"FlynnLives"
},
"label":"grid-config",
"name":"config-server",
"plan":"digital-frontier",
"provider":null,
"syslog_drain_url":null,
"tags":[
"configuration",
"biodigital-jazz"
],
"volume_mounts":[]
}
],
"encomSQL":[
{
"credentials":{
"username":"grid-db-user",
"password":"p4ssw0rd"
},
... abridged ...
}
]
}'
```### GET Permissions by Credential Name
You can use the `permissions_by_credential_name` method to view the list of permissions for a given Credential.
```ruby
> credhub_client.permissions_by_credential_name('/credential-name')
=> #,
#,
#
]>
```### POST Add Permissions
You can use the `add_permissions` method to add additional permissions to an existing Credential.
```ruby
> credhub_client.permissions_by_credential_name('/my-awesome-credential').count
=> 2
> new_permission = CredHubble::Resources::Permission.new(actor: 'uaa-user:b2449249', operations: ['read'])
> new_permission_collection = CredHubble::Resources::PermissionCollection.new(
credential_name: '/my-awesome-credential',
permissions: [new_permission]
)
> credhub_client.add_permissions(new_permission_collection)
=> #,
#,
#
]>
> credhub_client.permissions_by_credential_name('/my-awesome-credential').count
=> 3
```### DELETE Delete Permissions
You can remove any permissions for a given actor from a credential with the `delete_permissions` method which takes a `credential_name` and `actor`.
```ruby
> credhub_client.permissions_by_credential_name('/my-awesome-credential').count
=> 3
> credhub_client.delete_permissions('/my-awesome-credential', 'uaa-user:b2449249')
=> true
> credhub_client.permissions_by_credential_name('/my-awesome-credential').count
=> 2
```### GET Encryption Key Usage
You can fetch information about how many credentials are encrypted for the active (and inactive) encryption key
using the `key_usage` method. For more information, check out the official [CredHub docs](https://credhub-api.cfapps.io/#encryption-key-usage)
for this endpoint.```ruby
> encryption_key_usage = credhub_client.key_usage
=> #
> encryption_key_usage.active_key
=> 9000
> encryption_key_usage.inactive_keys
=> 20
> encryption_key_usage.unknown_keys
=> 0
```## Development
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
## Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/tcdowney/cred_hubble.
## License
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).