sandypockets
sandypockets

Reputation: 407

Challenges accessing/working with Rails credentials

I've been trying to access the API keys I set up in the Rails encrypted credentials. I added the keys to the file with Vim, and double checked they did save properly.

I added config.require_master_key = true to my test, development, and production files in config/environments.

But when I try to use one of the API keys, it returns nil.

I have the credentials set up like this:

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 1234567890

stripe:
  development:
    stripe_public_key: pk_test_1234567890
    stripe_secret_key: sk_test_1234567890

stripe:
  test:
    stripe_public_key: pk_test_1234567890
    stripe_secret_key: sk_test_1234567890
stripe:
  production:
    stripe_public_key: pk_live_1234567890
    stripe_secret_key: sk_live_1234567890

Then in the file I want to use it (new.html.erb) I'm trying to access the credentials within a script.

const stripe = Stripe("<%= Rails.application.credentials.stripe.stripe_public_key %>")

But it doesn't return anything.

I tried several other versions/syntax after digging through Stack Overflow and the Rails docs, but haven't gotten anything to work yet.

Also tried const stripe = Stripe("<%= Rails.application.credentials.stripe[Rails.env.to_sym][:stripe_public_key] %>") but no luck with that either.

When I run the server, and view the script in Chrome Dev Tools, it just shows as const stripe = Stripe("")

Worth noting that when I run rails credentials:show, the credentials are printed to the terminal correctly, so they do exist. I must just be accessing them incorrectly.

Upvotes: 2

Views: 2190

Answers (2)

Matthew
Matthew

Reputation: 1617

Separating the credentials into separate files per environment is valid but is not necessary. If you are solo or have a small team, a single credentials file and master key is simpler and easier to manage.

As pointed out in the accepted answer, each time you added :stripe at the root level of the credentials file, you overwrote the previous entry. To use different environment credentials in a global credentials file, remove the :stripe entries on lines 9 and 13:

# Used as the base secret for all MessageVerifiers in Rails, including the one protecting cookies.
secret_key_base: 1234567890

stripe:
  development:
    stripe_public_key: pk_test_1234567890
    stripe_secret_key: sk_test_1234567890
  test:
    stripe_public_key: pk_test_1234567890
    stripe_secret_key: sk_test_1234567890
  production:
    stripe_public_key: pk_live_1234567890
    stripe_secret_key: sk_live_1234567890

You can then access the credentials statically:

Rails.application.credentials.stripe.development.stripe_public_key

Or dynamically per environment (note you can mix and match hash syntax with dot syntax):

Rails.application.credentials.stripe[Rails.env.to_sym].stripe_public_key

You could also put the environment at the top level (especially if there were other environment specific credentials) and remove the redundant reference to stripe in the final node:

development:
  stripe:
    public_key: pk_dev_1234567890
    secret_key: sk_dev_1234567890
test:
  stripe:
    public_key: pk_test_1234567890
    secret_key: sk_test_1234567890

The credentials path would then be:

Rails.application.credentials[Rails.env.to_sym].stripe.public_key

Upvotes: 0

rewritten
rewritten

Reputation: 16435

As @DennyMueller pointed out in the comments, the problem was that the 'stripe' key was overwritten in the file and only the last one ended up existing in the configuration.

It's anyway useful to point out that this is not the way Rails expects to manage credentials that depend on environment. Instead, you should have separate files config/credentials/development.yml.enc and config/credentials/test.yml.enc, which are generated by running

rails credentials:edit --environment development
rails credentials:edit --environment test

So each credentials file should not have the environment name as a key anywhere inside.

Upvotes: 3

Related Questions