Apps, AuthN & Speckle (2.0)

Hey there @Speckle_Insider! This is a quick post on how authentication with the server will work in 2.0; we’ve revamped things a lot to make it easier for developers to extend the functionality of Speckle in their own apps, and simultaneously more secure for end users.

First off, why? We have seen that Speckle 1.0, against all odds, was extensively extended in various ways:

  • as stand alone frontend web applications
  • integrated in stand alone back-end only server apps
  • as backend+frontend applications
  • as analysis routines in either Python or .NET
  • as (.NET) desktop applications

Consequently, we needed a more mature approach to how the whole system is wired up in order to support the growing use-cases and allow for the ecosystem to grow. After going through a couple of books on OAuth2, dredging through existing implementations, and blatantly looking at how Github and others do it, we’ve just merged a PR in the 2.0 Server repo that wraps things up on this front.

So, how does all this work? Before we start, we’d like to clarify that this post refers to specifically authentication, and not authorization.

  • Authorization (authZ) controls who has access to what resource; it’s not the focus of this post.
  • Authentication (authN) controls how a user can delegate access to other applications (pieces of software) that then act on their behalf.

API Tokens

Similar to 1.0, all access to the API is done through bearer tokens that need to present in the Authorization header of each request. There are several ways to create/obtain these tokens, which we’ll describe below. First, a few important notes on tokens in general:

Token Scopes

Each token has a set of associated scopes to it which limit what actions it can do. For example, you could have a token that is only allowed to read streams and your profile information. Alternatively, you could have a token that is allowed to search for other users on the server, read your existing streams, create new ones, etc.

As Speckle 2.0 will grow with functionality, new scopes will be made available. Currently there are:

let coreModuleScopes = [ {
    name: 'server:setup',
    description: 'Edit server information.'
  },
  {
    name: 'tokens:read',
    description: `Access your api tokens.`
  },
  {
    name: 'tokens:write',
    description: `Create and delete api tokens on your behalf.`
  },
  {
    name: 'streams:read',
    description: 'Read your streams & and any associated information (branches, tags, comments, objects, etc.)'
  },
  {
    name: 'streams:write',
    description: 'Create streams on your behalf and read your streams & any associated information (any associated information (branches, tags, comments, objects, etc.)'
  },
  {
    name: 'profile:read',
    description: `Read your profile information`
  },
  {
    name: 'profile:email',
    description: `Access your email.`
  },
  {
    name: 'users:read',
    description: `Read other users' profile on your behalf.`
  },
  {
    name: 'users:email',
    description: 'Access the emails of other users.'
  } ]

Token Lifetime

Tokens also have a certain lifetime after which they’re no longer valid. This helps with automatically blocking access to long forgotten apps. Written a little script two years ago that you’ve totally forgot about, but the token’s nicely pasted in the codebase since you’ve never published it? Well, now that’s safe even if someone else somehow snitches it - it probably expired.

Personal Access Tokens

As a developer, you can now create personal access tokens that you can use to delegate access to your script on your behalf, similar to how Github’s Personal Access Tokens work.

When you create them, you can assign assign to them whatever scopes & lifetime you want to, just remember to limit both to the minimum to be safe.

Apps

Once your beyond hacking phase, you’ll probably want to create & publish a speckle app that others can use. As a developer, you can:

  • register apps that others can use (or not),
  • manage the apps you have created - edit name, description, redirect url, scopes, and delete.

Once an app is registered on a server, users can now delegate access to it for the set of scopes that the developer registered for that application. Once the delegation process is successful - the user approves it - they will get redirected to the url that the developer specified.

Of course, as an end user, you have full control and visibility on the apps you have authorized. You can:

  • see all your authorized apps (apps that you have granted access to),
  • revoke access to any of the above,
  • check out any publicly listed apps on this server (optional at this stage)

Extras on app types

Extras on app types

Note: broadly speaking, there are two type of apps:

  • Apps that act on behalf of a user - supported :white_check_mark:
  • Apps that can act with their own identity - not currently supported :stopwatch:

We’ll do a more in detail post later (or when we write up some dev docs) on how the authentication flow with the 2.0 Speckle Server actually works. For the geeks out there, here’s a short summary, or some important points:

  • We are supporting the authorization_code flow with PCKE only for public and confidential clients.
  • We do not support dynamic scope requests for apps. We only support pre-registered scopes for each app.
  • If an app is edited in any way - name, scopes, etc. - all its tokens get revoked and users will need to re-authorize it.

Clients are usually split into two categories: public and private. Public clients cannot realistically hold a secret, whereas private ones can. For example, a front-end only web application is a public client; same goes for the desktop connectors. A private client can be a server-side application, which can realistically store an application secret in, for example, a .env file or provide it during the CI/CD process.

Clients are protected by:

  • Using exclusively a pre-registered redirect URL.
  • Native apps (desktop): registering a custom application scheme (speckle://).
  • PKCE (Proof of Key For Code Exchange).
  • a client id & client secret, but the clientSecret is superfluous in the case of public clients.

Examples

The 2.0 server already comes with two applications that demonstrate this flow (warning - there might still be bugs). These are:

  • The main web frontend application - accessible at the server’s default url, and
  • The GraphQL explorer - accessible at your server’s url + /explorer.

Here’s a gif showing how I’m logging in to the graphql explorer application:

To have this working locally on your computer, just run npm run dev:all from the command line in your server repo folder. Note: there are still some issues to iron out, so tread carefully!

Wrapping Up

We’ve put a lot of work into making Speckle 2.0 developer friendly and extensible - and apps are just a small part of that. We hope that writing Speckle Apps will be fun and effective, and we can’t wait to see what you’ll do with them!

3 Likes

Always excited to read up on the speckle goods! Even if I don’t know much about the topic :expressionless: but I do have a couple of question…

If Projects jump into Speckle 2.0, would the token grant access to projects? Could those limited actions be applied to a Speckle Project hierarchy?

2 Likes

Great shout!

Projects at the moment are on hold, but they’ll make their way in at one point. The authorization (authZ) parts around this are a bit more tough, hence we’re focusing on the more straightforward stuff at the moment.

We’ll first want to see how stream branches and commits will be used, and then make an informed opinion on how to develop higher level functionality like projects (maybe we’ll call them teams? just wild noise thoughts here).

Aaaanyway, petty excuses aside:

This would mean at least two extra scopes being added, something on the lines of projects:read and projects:write, which would allow an app to programatically create projects with that token. Of course, this could be refined/expanded to projects:${read,write}:streams for adding/removing streams to projects, and projects:${read,write}:users for actually managing the team behind a project. TBC!

3 Likes

Good point, @haitheredavid. In our Speckle servers, we will be pushing people more and more to use projects, so that’s a key element of the server for us.

2 Likes

ah great deets! It’s good to know how they potentially will be fitting in. thanks for the info :100:

I would mos-definitely support the renaming for Projects/Teams/Club/Squad!

@daviddekoning (hi hello! nice to virtually meet) ah that’s great to know! I would be curious to know if you have any plans or strategies towards implementing em’ for Speckle 2.0… I haven’t done much with projects besides messing with them in GH, but I plan on integrating them into one of our speckly prototypes

1 Like

no detailed plans yet, but since all of our design work is organized in projects, having the same vocabulary in Speckle helps to get people on board. The most common use case for sharing data is between members of a project team, so it makes sense to be able to directly specify access that way.

We’ll definitively do another round of discussions on projects! Would though like to keep the discussion focused on the authentication parts if possible.

To make a transition, I can totally see a custom management application built as a “speckle app” that’s can be tailored to the company’s specific needs. This route would allow for a much more tight integration with the business internals, as well as any other company management systems (time tracking, job codes :wink:, project specifications, etc.).

1 Like

thanks for bringing us back to the topic at hand, @dimitrie! It’s great to see a more robust authentication strategy.

I am not an expert in this field, so please forgive some silly quesions:

Revoking tokens on app update: are they revoked when the app registration on the server is modified, or when the app itself is updated. For instance, if we release a new version of SpeckleGSA, will all users have their tokens revoked, or will that only happen if we change the scope in the server registration?

Registering an app on a server: is this something that any developer can do, or does a server administrator need to register the apps?

1 Like

Perfect questions! These are things I should’ve covered in the original post :grimacing:

Yep, that’s bound to happen. But the regarding desktop applications, that’s actually different because of how secrets can be handled on the users’ devices. Which brings us to:

SpeckleGSA is a desktop application, and through the Speckle Core .NET SDK it will have access to all accounts stored on that specific machine. Consequently, this will not happen; we took the decision to centralise account management and permissions around connectors through the WIP “Desktop Manager” for the sake of user experience.

Why? We didn’t want people logging into every single connector for every single account they might have. As you can imagine, let’s say 3 connectors and 3 accounts - that’s already 9 logins you’d need to do… Currently, you only need to log in 3 times for each of your accounts once.

We will need to negotiate a bit the scopes granted to connectors, but so far we have 'streams:read', 'streams:write', 'profile:read', 'profile:email', 'users:read' assigned to them. If, as we go, we add more, we can always update that list.

The way it’s implemented right now, anybody with an account on that server can register an app - a bit like Github which doesn’t really place any restrictions on this.

We can discuss in the future to add a bit of finer grain control over this (e.g. admins will need to approve an app becoming public (ie, available to everyone on that server) - this is just a of the top of my head suggestion).

Would be happy to hear what you guys have in mind here! Agenda wise, we’re definitively aiming for an as open as possible approach, so we encourage people to hack but we do understand some more levers might be required. Just keep in mind that an app, alone, cannot do anything without the permission of the end user!

2 Likes

Thanks, @dimitrie, that makes sense for desktop apps. For web apps, though, the tokens are revoked on an update to the registration, right? Can webapps that connect to speckle be updated without requiring new tokens?

As far as our plans go - a major area that we are looking at is using Speckle to support automatic design workflows. In this situation, a user would authenticate a workflow manager app to connect to their Speckle streams (all streams, a project’s streams or a specific stream), and then the workflow manager would retain that auth token (it is a private client as per your post), and would use it to access Speckle data each time it runs.

As far as auth is concerned, I think that what you are proposing works well for this use case. We will also be making changes to the server (persistent notifications) and to the GH senders and receivers (adding an option to set the server and auth token via component inputs). We’ll be pushing these updates to our 1.0 fork over the next month or so - it’s out of scope for this thread; let me know if it would be interesting for me to set up a separate thread.

oh, and am I right to assume that AD integration is supported?

Hi @daviddekoning, sorry for replying late!

Whenever an app is updated - name, description, required scopes - its tokens are revoked. This just means that users would need to re-authenticate it (re-sign in). It isn’t a painful process!

Currently it’s not, but it’s because I don’t have an AD point to test against :slight_smile: There’s literally no other reason why it shouldn’t be able to come back though. We can have a chat about it later!

Would love to see them coming up, mostly so we can coordinate on the 2.0 ones and make sure we’re aligned there. Ie, with 2.0 visual programming components, we’re splitting them in “advanced” and “defaults”. There are indeed subjects for a next thread, good reminder there :bowing_man:

2 Likes