-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[server] Provide token-based API access #1868
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
5fbb6e8
to
0d2a464
Compare
akosyakov
reviewed
Sep 18, 2020
akosyakov
reviewed
Sep 18, 2020
akosyakov
reviewed
Sep 18, 2020
akosyakov
reviewed
Sep 18, 2020
akosyakov
reviewed
Sep 18, 2020
akosyakov
reviewed
Sep 18, 2020
akosyakov
approved these changes
Sep 18, 2020
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.
it works for me besides some leftovers
0d2a464
to
6bd0571
Compare
32 tasks
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR introduces token-based access to Gitpod's JSON-RPC over Websocket API.
We will use this kind of access for moving functionality to supervisor and integrating IDE's other than Theia.
Token-based Authentication
We already have API tokens in Gitpod: the
GitpodToken
previously introduced for the GraphQL admin API. This PR re-uses those tokens and introduces a new token type:MACHINE_API_TOKEN == 1
. These tokens can be used to authenticate against Gitpod when connecting to the new websocket API endpoint/api/v1
. Sending anAuthorization: Bearer <token>
header will provide access to the API.Tokens are always associated with a user and by default have the same rights as the user has - on the functions the token is scoped for (see below). To create a new token use the
generateNewGitpodToken
function. For now there's a bit of a chicken and egg problem: one needs to use the classic session-based authentication to create an API token in the first place. If we ever find that to be a problem (e.g. in combination with new IDE's/supervisor token integration), we could consider producing a token per workspace and making that available as OTS, or allowing the owner token to create specifically scoped tokens.We are introducing the new
/api/v1
API endpoint has different requirements from the old/api/gitpod
one:/api/gitpod
endpoint where some operations can happen without user session (e.g.getBranding
)./api/v1
isn't meant for public consumption, but sooner than later we'll have such a public API. It's a good idea to implement the versioning pattern now. Having a special endpoint for the dashboard (/api/gitpod
) also gives us more control over which API version we want to use in the dashboard.Scoping
Tokens are constrained along two dimensions: functions and resources. Functions refer to the functions of the Gitpod JSON-RPC API, and resources to various resources within Gitpod. Function scoping is enforced on the RPC interface, resource scoping is enforced throughout the server implementation.
Function Scopes
All tokens must explicitly list the functions they can use, as part of their scopes. E.g. a token with
[]
as scopes cannot access a single function of the API. Function scopes are written asfunction:<functionName>
, e.g.function:getWorkspace
. A token's scopes are defined when the token is created. Note: you can not exceed the scope of your own authentication when creating new tokens, e.g. if your current authentication/token only hasfunction:generateNewGitpodToken
andfunction:getWorkspace
, you cannot create a new token withfunction:startWorkspace
.Resource Scopes
All tokens must explicitly list the resources they can use, as part of their scopes. E.g. a token with
[]
as scopes cannot access a single resource. Other than the scheme described below, there's a specialresource:default
scope which grants the same access to resources that the token's owner has. Mixing the default scope with other explicit resource scopes behaves just like mixing other resource scopes: they are additive in what they allow.Resource scopes consist of three elements:
resource-access.ts
, and includesworkspace
,workspaceInstance
,gitpodToken
, andsnapshot
.create
,update
,get
,delete
.We encode resource scopes like this:
resource:<kind>::<subjectID>::<op1>,<op2>
. There's a marshal and unmarshal function available.Other access-limiting concepts in Gitpod
The resource and function guards are not the first - or only - means of controlling access in Gitpod. Below is a comparison to the existing methods:
admin
permission grants access to the Admin dashboard. These permissions are orthogonal to function/resource scoping, in that they limit access beyond that function scoping does. E.g. if a token has thefunction:adminListWorkspaces
scope, the function call will only succeed if the token's user has theADMIN_WORKSPACES
permission.checkUser/checkUserBlocked
: it's actually theGitpodServerImpl
that checks if a user is present and if it isn't blocked. This part of the authentication process remains as it is. Using a token for authentication provides the token's owner to the server, hence all operations happen in the name of token owner, as doescheckUser
andcheckUserBlocked
. Thus, if a token owner gets blocked, so do all of their tokens.How to test?
To get the token hash, run
where
foobar
is your token.2. connect to the API endpoint, e.g. using websocat. Notice the bearer header. Replace foobar with whatever your token is:
Caveats
Thanks
to @AlexTugarev for the super helpful discussions, listening to my Node/TS rants and help wading through the JSON RPC stack.