-
-
Notifications
You must be signed in to change notification settings - Fork 263
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
do not allow EnvironmentVariableAccess in initializers #1229
Conversation
|
Hmmm... Guess I was a bit too quick. How about we limit the include to
Would that be an option? |
I have left two comments. Can you update these and squash the commits? |
Updated, squashed, and added specs for the new cases 👍 |
Thanks! |
I'm confused: With this rule enabled, how can a Rails app read env vars at all? E.g., in my initializers, I A couple people (or maybe just one person?) has said that the Rails configuration lib can read env vars and check them at boot time. But no one has provided code showing this, so the rule was set disabled by default. I'm skeptical the lib does this: I couldn't find mention of this check-env-var-at-boot feature in the Guide. In a nutshell, this rule seemed to be on shaky ground before this change. And now that all initializers are off-limits to |
From the PR description:
So what you can do is # In config/slack.yml
default: &default
client_id: <%= ENV["SLACK_CLIENT_ID"] %>
client_secret: <%= ENV["SLACK_CLIENT_SECRET"] %> # In application.rb
module MyApp
class Application
config.slack = config_for(:slack)
end
end
# In rest of the app
Rails.application.config.slack.client_id Similarly, secrets should be in # In config/credentials.yml.enc
secret_key_base: 3b7cd72...
some_api_key: SOMEKEY
system:
access_key_id: 1234AB You can do # In rest of the app
Rails.application.secrets.some_api_key
Rails.application.secrets.system.access_key_id That way
If you cannot or don't want to use the Rails secrets/credential mechanisms for whatever reason (we don't), you can put everything in Hope that helps! |
Thanks @markokajzer. So if I understand it correctly, under this rule, |
I'm not sure I fully understand the argument about the app already being semi-initialized at the point it starts loading the initializers directory. The idea of that makes sense, but I'm not sure how we extend that logic to mean that the initializers are an inappropriate place to read from ENV. My understanding is that the entire reason we say "don't mess with ENV post-initialization" is because missing configuration wouldn't be caught at boot (obviously bad). This is the exact reason I read directly from ENV from within initializers in the first place. I'm willing to be wrong here, but I'm really not thrilled by the idea of adding an extra YML file (where there was not one before) for each separate configuration I already have set up, which is just a bunch of boilerplate (and another layer of indirection) for mapping ENV variable names to configuration names. |
Unfortunately, that is literally the suggested approach from the Rails docs. Rails changed this a couple of times throughout the versions and years, and other people from the community dislike the different configuration options for similar reasons. Here's an example from searls.
i don't think it was ever about "messing" with anything. after all it was just access to to me, this was about enforcing one way of doing this (now everything is pushed towards similarly, if our env variable is an actual secret, maybe we can put it in Rails credentials, where it will be encrypted automatically and actually safe, in contrast to just having there are other options as well
nevertheless, i'm just trying to explain some points here. I'm more then willing to take the L here and revert this. |
I appreciate the extra thoughts & time, thanks @markokajzer. This certainly is far from a hill worth dying on as far as I'm concerned, and I think I am aligned on the idea that the linter should have an opinion on the correct way to do things like this, and I really can't argue with the idea that it's how the Rails guide wants you to do it. The link you included is helpful as it's the same issue I'm having, and I also happen to be using standardrb, so looks like this won't be something I have to mess with configuration wise, either. In the end, the discussion is what's important - if I could suggest anything extra, for what does appear to be an immediately-noticed change & resulting disagreement, maybe a small disclaimer in the Rubocop docs which has a very short rationalization for the choice? Even if it were just to explain that this is the "correct" way to do it as far as the Rails guides are concerned, and that enabling the cop by default is preferable to having no cop at all. Cheers. |
The description of the cop states
Do not access ENV directly after initialization.
. However in some ways, the application is already initialized when we get toconfig/**/*.rb
:config_for(:service)
is already available to read config fromservice.yml
Rails.application.credentials
is already available to read application credentials / secretsI think it could make sense to push people to move their config in either of these two places. If they want to access their config / secrets in a Ruby file, let's say,
config/initializers/service.rb
they can usecredentials
orconfig_for
, no need to accessENV
directly again.Also see https://guides.rubyonrails.org/initialization.html.
I understand this is a bit nuanced, so if this is not desired, that's completely fine ✌️
Before submitting the PR make sure the following are checked:
Commit message starts with[Fix #issue-number]
(if the related issue exists).master
(if not - rebase it).bundle exec rake default
. It executes all tests and runs RuboCop on its own code.{change_type}_{change_description}.md
if the new code introduces user-observable changes. See changelog entry format for details.If this is a new cop, consider making a corresponding update to the Rails Style Guide.