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
Support for storing app keys in settings #1399
Comments
I'm not recommend to you have any tokens and secret codes in repository. Same recommended in many books Two scoops of Django one of them. |
Yeah, i know that having tokens in settings is not a good practice, but you could load them from environment variables to avoid saving them in your repository. Loading the data with an external script is more or less what i do now. |
I'm prefer copy minimal instance of DB to new instances of project, other users can copy tokens in different way. |
Yeah @cdvv7788 I agree with you, an optional utility would be nice. I ended up doing exactly as you describe:
I also understand your point though @Akay7, most users are probably doing this once or twice in the admin and don't have to worry about it again. |
I support this idea. In my opinion I would expect to be able to add the tokens from settings and Allauth is able to read it directly from there without adding it to the Django Admin. |
See #125 for background info |
Although it's perhaps best practice to store these keys as environment variables, I suspect that a number of django-allauth users would not know this, and would then put their keys in the settings file, worsening their security. What about a configuration option, |
@stringsonfire I don't see it necessary. If you add settings variables, the developer should be the one who chooses how to store the information. Why to use a JSON file when you can do it in the settings file directly? |
@andresgz Because your settings files are in your repo, any keys that may be stored in them will be clearly readable for anyone who has (or gains) access to your repo, creating an unnecessary security vulnerability. By moving these keys to environment variables or a separate file not in your repo (added to your .gitignore), someone with malicious intent having or gaining access to your repository represents less of a threat. Check out Two Scoops of Django, well worth a read. I only suggest a JSON file as they suggest it's the most appropriate format if you can't use environment variables. |
I am closing this thread. As indicated, the motivation can be found over at #125. Note that I agree that keeping the keys in the DB is not everybody's cup of tea. At some point in time, I would like to revisit this and allow for reading the |
@pennersr if you agree in principle, but don't have the time to do this, should this be added to a Todo section in the docs, welcoming anyone to work on it and preventing duplicate feature requests in future? |
I closed it because this is not easily changed without breaking compatibility in a bad way. So this is definitely not something high on the priority list, but let's indeed reopen so that people have something to vote on. Thoughts:
|
@pennersr as i initially proposed, we could add a management command to populate socialapps from settings data. We could keep current behavior without breaking anything, and still make it easier to keep that data in the settings. This could work until we decide if we move forward to a full settings setup. |
I would prefer to focus this ticket on the "full settings setup" -- I feel adding a management command is a bit too much of a temporary/kludgy solution... |
In that case, i vote for the removal of the model. Keeping deprecated pieces around does not feel right. |
would much prefer this. Loading via environment variables is done for many api keys that I use, it makes it confusing to have to add via django admin |
I created a fork which implements automatic model creation/retrival (using django get_or_create) using provider specific settings. It seems to work, but I can understand that this implementation isn't preferred as it potentially leaves rogue SocialApp models. Anyway, for people who desperately want/need to use environment variables for secret/application id, take a look here: https://github.com/Lamelos/django-allauth |
I'm using django-environ, so I'd also like to store the settings in the dotenv. For now I'm using a script that I wrote based on @getup8's: register_social_accounts.py. I'd really like to see something like that included until there is a purely settings-based solution. |
Reasons why this request is important:
|
Considering the following:
I get that it's not idiomatic for these values to be pulled from the DB. However, given that once allauth is configured a user of the site can manage auth methods (rotating keys, adding new and removing old) is a huge benefit. If you wanted to create a large offering of social integrations across multiple sites run by the same django installation you would end up with a deeply nested dict in your settings (aka: a nightmare when you need to rotate that one key... or maybe it's an old key that two domains use, need to find it in multiple places). I'm only partially convinced about the argument that we need to prevent devs from exposing their secret values by accidentally committing them to a repo (good thought, not a great reason for design decisions to me, the naive approach seems to be "create a setting and a management command to set up the models you need" so the current implementation doesn't really prevent someone potentially committing these secrets into a repo). I'm more interested in encrypting secrets/tokens. User tokens are one thing (yes, it's embarrassing to be hacked and expose user tokens), but the app secrets are a whole other thing. # socialaccount/models.py
class SocialApp(models.Model):
...
secret = app_settings.SECRET_FIELD_CLASS(verbose_name=_('secret key'),
max_length=191,
help_text=_('API secret, client secret, or'
' consumer secret'))
...
class SocialToken(models.Model):
...
token_secret = app_settings.SECRET_FIELD_CLASS(
blank=True,
verbose_name=_('token secret'),
help_text=_(
'"oauth_token_secret" (OAuth1) or refresh token (OAuth2)'))
...
# socialaccount/app_settings.py
class AppSettings(object):
...
@property
def SECRET_FIELD_CLASS(self):
return self._setting('SECRET_FIELD_CLASS', CharField)
... The above code intends to allow one to override the |
If secrets are important, they should not be in the DB in plain text. Securing secrets is not a new problem that needs to be solved with custom encrypted fields in the database. We now have lots of better, more secure options at our disposal:
When you store secret values in the database, everyone has the same poor security for their secrets. When you store values in the runtime environment (file in the file system, env variables, etc), you're allowing people who do take security seriously to follow the best practices for secrets management. |
I agree with using a more secure data store but I think what this suggests is tying this package into some additional storage dependency. Either every sensitive field is stored elsewhere (modify the ORM to load field X from storage mechanism Y). Or store this entire model in another system entirely (second ORM for the subset of models requiring this level of security). An encrypted field solution is trying to be a minimally invasive change. Maybe specific fields from some other storage mechanism is not as complex as I think but I feel like moving into a separate storage mechanism for this is ballooning the solution. |
See 9f65d3c: |
I have been using django-allauth for a while now and every time i create a new instance i wonder why the data required for a social connection is hold into a model instead of the settings. This makes somewhat difficult having several instances and complicates the automated deployment of new instances.
I know that some additional data is stored and related to the socialaccount object, but that is not something that cannot be done with settings.
Is there any specific reason that i am missing for this design decision?
PD. not complaining, just curious.
The text was updated successfully, but these errors were encountered: