Skip to content
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

Added create service method #619

Merged
merged 11 commits into from
Dec 13, 2023
Merged

Conversation

jmaruland
Copy link
Collaborator

@jmaruland jmaruland commented Dec 12, 2023

This PR partially addresses #618 as part of the NSLS2 tier 2 data security project

@jmaruland jmaruland changed the title Added created service method Added create service method Dec 12, 2023
@danielballan
Copy link
Member

To summarize:

Tiled has had a hidden feature of "service principles", Principals which:

  • Have type "service" instead of the usual type "user"
  • Have no identities and therefore cannot login / create Sessions
  • But may have API keys

Up until this PR, there has been no way to actually create a Service Principal, unless you log into the SQL database and hand-code queries. This PR:

  • Add a new scope, write:principals, conferred to the admin role
  • Adds a new HTTP endpoint, POST /auth/principal?role={role} to create a Service Principal, protected by write:principal scope
  • Adds a method in the Python client, c.context.admin.create_service_principal(role)
  • Promotes and generalized the test fucntion _create_api_key_for_other_principal to a public method, c.context.admin.create_api_key_for_other_principal

The intended flow that is:

  • Admin creates Service Principal for a given purpose
  • Admin creates an API key on behalf of that Service Principal, ideally with a note, expiration, and perhaps restricted scopes
  • Admin that uses that to set up a service with access to Tiled

The usual AccessControlPolicy mechanism may be applied, same as with normal user accounts, to restrict which nodes the service can access.

@danielballan
Copy link
Member

This is going to get rushed into deployment to test with beam on a dummy experiment, but review is appreciate at any point, before or after merge.

Copy link
Contributor

@dylanmcreynolds dylanmcreynolds left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't really go line by line, but looks good to me.

Copy link
Contributor

@padraic-shafer padraic-shafer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks really good.

  • I added a few non-critical comments that you could commit now or consider later.
  • I added two suggestions regarding the new scope that I will address now.

tiled/server/authentication.py Outdated Show resolved Hide resolved
request: Request,
principal=Security(get_current_principal, scopes=["read:principals"]),
db=Depends(get_database_session),
role: str = Query(...),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a future PR, should we consider accepting this parameter from Query or Body?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My thinking was:

  • The role name will never be large (i.e. it will fit in the URL always).
  • The role name is not sensitive (i.e. not a credential).
  • Query params are simple.

I guess JSON bodies are also simple, though. Is there a particular driving use case?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking only for flexibility, but I agree that there is not a strong case for changing at the moment.

tiled/client/context.py Outdated Show resolved Hide resolved
tiled/client/context.py Outdated Show resolved Hide resolved
tiled/client/context.py Outdated Show resolved Hide resolved
tiled/client/context.py Outdated Show resolved Hide resolved
tiled/_tests/test_authentication.py Show resolved Hide resolved
tiled/authn_database/core.py Outdated Show resolved Hide resolved
@padraic-shafer
Copy link
Contributor

@danielballan I leave the merge for you. All looks good except the scopes permission on the new endpoint, which I committed so that you can review.

@padraic-shafer
Copy link
Contributor

One more thing to consider (for a future PR?): Should the "write:principals" scope be automatically stripped from "service" accounts?

I.e., do we want to rule out at an early stage the possible perpetual generation of service accounts/keys? Should only a living admin should do this, or are there envisioned workflows where an automation chain would be useful?

danielballan and others added 3 commits December 13, 2023 06:24
@danielballan
Copy link
Member

Thanks for the critical fix and the suggestions. I've addressed most, and spun out one into a follow-up GH issue.

Should the "write:principals" scope be automatically stripped from "service" accounts?

It's a good point. I almost went ahead and implemented this---simple enough---but I think discussion about use cases for services is needed first. I can imagine use cases for services that manage Principals, such as cleaning up disused user Principals, or even spawning large numbers of Service Principals that are tightly scoped in access (e.g. to a specific proposal).

Exactly how will implement this will matter: we may not want a complete ban, but perhaps distinct service Roles so that most Services Principals cannot spawn other Services Principals. #620 is a good place to explore this.

@danielballan danielballan merged commit 62b48d9 into bluesky:main Dec 13, 2023
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants