-
Notifications
You must be signed in to change notification settings - Fork 3
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
Authenticate endpoints and validate user state_code in metrics requests #546
Conversation
…ed, don't verify if auth is disabled
spotlight-api/README.md
Outdated
@@ -44,6 +44,8 @@ Expected backend environment variables include: | |||
|
|||
- `GOOGLE_APPLICATION_CREDENTIALS` - a relative path pointing to the JSON file containing the credentials of the service account used to communicate with Google Cloud Storage, for metric retrieval. | |||
- `METRIC_BUCKET` - the name of the Google Cloud Storage bucket where the metrics reside. | |||
- `AUTH_ENABLED` - whether or not we should require authentication to access our endpoints. Currently only used in staging to make the entire site private. No need to enable this locally unless you are developing or testing something auth-related. If set to `true` then `AUTH0_APP_METADATA_KEY` **must** be set to a supported value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This means we'll need to change the staging environment to make sure these keys are set
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea good call, do you know where/how to do this? I'm actually not sure, I forget where the Spotlight backend is hosted. I see something both in Firebase and also GCP.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the backend is in App Engine, there are GAE config files in a shared 1password document that we have to update and then store locally (untracked) in order to deploy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@colincadams do you know how to set the staging environment variables?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@terryttsai @macfarlandian so is it sufficient to update gae-staging.yaml in public-dashboard-untracked-config-files.zip in 1pass? How do those get pulled in during deploy?
@terryttsai you don't have access to 1pass, right? So I can do this for you
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think so, I don't see that file in 1pass
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that zip file is the "master copy" but then you have to download it and copy those files into their respective locations in your working directory. (The deployed backend does not actually use the .env
file, which is a little confusing, it uses the environment config in the yaml for that environment. The .env
is just for development.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see. Are spotlight deploys just done manually by whomever wants to then? By running gcloud app deploy gae-staging.yaml --project [staging_project_id]
? Or is there a more formal process?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nope that's as formal as it gets
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool, ok this all makes sense, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking good to me, thanks for doing the backend component of this too @terryttsai just to be super safe!
spotlight-api/README.md
Outdated
@@ -44,6 +44,8 @@ Expected backend environment variables include: | |||
|
|||
- `GOOGLE_APPLICATION_CREDENTIALS` - a relative path pointing to the JSON file containing the credentials of the service account used to communicate with Google Cloud Storage, for metric retrieval. | |||
- `METRIC_BUCKET` - the name of the Google Cloud Storage bucket where the metrics reside. | |||
- `AUTH_ENABLED` - whether or not we should require authentication to access our endpoints. Currently only used in staging to make the entire site private. No need to enable this locally unless you are developing or testing something auth-related. If set to `true` then `AUTH0_APP_METADATA_KEY` **must** be set to a supported value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yea good call, do you know where/how to do this? I'm actually not sure, I forget where the Spotlight backend is hosted. I see something both in Firebase and also GCP.
stateCode !== tenantId.toLowerCase() && | ||
stateCode !== "recidiviz" | ||
) { | ||
res.status(401).json({ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we should throw different error messages in these different cases:
- AUTH0_APP_METADATA_KEY is empty
- req.user?.[AUTH0_APP_METADATA_KEY] is empty
- req.user?.[AUTH0_APP_METADATA_KEY]?.state_code is empty
- req.user?.[AUTH0_APP_METADATA_KEY]?.state_code is set, but not equal to the tenant ID
Might be helpful for debugging?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I can assert that AUTH0_APP_METADATA_KEY
is defined and we'll see the error in the logs if it's not? If any of the rest is empty we know the user app_metadata hasn't been configured properly. We could have different logs though I would want to return the same 401 error to the client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep sounds good, whatever you think is best! Just thought I'd point it out
spotlight-api/README.md
Outdated
@@ -44,6 +44,8 @@ Expected backend environment variables include: | |||
|
|||
- `GOOGLE_APPLICATION_CREDENTIALS` - a relative path pointing to the JSON file containing the credentials of the service account used to communicate with Google Cloud Storage, for metric retrieval. | |||
- `METRIC_BUCKET` - the name of the Google Cloud Storage bucket where the metrics reside. | |||
- `AUTH_ENABLED` - whether or not we should require authentication to access our endpoints. Currently only used in staging to make the entire site private. No need to enable this locally unless you are developing or testing something auth-related. If set to `true` then `AUTH0_APP_METADATA_KEY` **must** be set to a supported value. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
the backend is in App Engine, there are GAE config files in a shared 1password document that we have to update and then store locally (untracked) in order to deploy.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
tested this locally and it looks great! just had a few minor notes
Pull Request Test Coverage Report for Build 2272685546Warning: This coverage report may be inaccurate.This pull request's base commit is no longer the HEAD commit of its target branch. This means it includes changes from outside the original pull request, including, potentially, unrelated coverage changes.
Details
💛 - Coveralls |
@@ -30,6 +30,7 @@ type ErrorAPIResponse = { error: string }; | |||
type FetchMetricOptions = { | |||
metricNames: string[]; | |||
tenantId: TenantId; | |||
getToken: () => Promise<string>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what was the issue here, importing the datastore into this module was causing some kind of dependency resolution problem? I wonder if it might be better solved by moving the API methods into a datastore class rather than drilling this function through all of our content models? (I don't know off the top of my head if that would cause different problems but it seems like it might be cleaner, if it works)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I was going to ask here, if it would be easy to move the API methods into one of our stores and call it without having to pass it down all these content models?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because I was getting nasty dependency cycles with trying to import the Datastore in fetchmetrics
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you should give it a try! IIRC I kept them separate because at the time they didn't really have any dependencies, but there isn't any structural reason why they have to be set up that way
efffd4f
to
552814e
Compare
Description of the change
Authenticate endpoints when auth is enabled and validate that user state_code matches the requested tenantId in metrics requests.
This ensures that users with a state_code in one state cannot request data from another state.
Users with a state_code of
recidiviz
can request data from any state.Type of change
Related issues
Checklists
Development
These boxes should be checked by the submitter prior to merging:
Code review
These boxes should be checked by reviewers prior to merging: