Skip to content

Conversation

@geropl
Copy link
Member

@geropl geropl commented Oct 9, 2023

Description

Follow-up for: #18893

This PR:

  1. split the EnhancedLogContext as suggested here
  2. Cleanup of the SpiceDbAuthorizer API/bindings as suggested here
  3. Passes ZedTokens to readPermissions calls as well (turns out we are calling them more often then expected)
Summary generated by Copilot

🤖 Generated by Copilot at dcd42e3

Refactor the server component to use SpiceDB for authorization and simplify the log context module. Add TypeScript bindings and code generation for SpiceDB protobuf files.

Related Issue(s)

Fixes #

How to test

Documentation

Preview status

Gitpod was successfully deployed to your preview environment.

Build Options

Build
  • /werft with-werft
    Run the build with werft instead of GHA
  • leeway-no-cache
  • /werft no-test
    Run Leeway with --dont-test
Publish
  • /werft publish-to-npm
  • /werft publish-to-jb-marketplace
Installer
  • analytics=segment
  • with-dedicated-emulation
  • workspace-feature-flags
    Add desired feature flags to the end of the line above, space separated
Preview Environment / Integration Tests
  • /werft with-local-preview
    If enabled this will build install/preview
  • /werft with-preview
  • /werft with-large-vm
  • /werft with-gce-vm
    If enabled this will create the environment on GCE infra
  • with-integration-tests=all
    Valid options are all, workspace, webapp, ide, jetbrains, vscode, ssh. If enabled, with-preview and with-large-vm will be enabled.
  • with-monitoring

/hold

@geropl geropl force-pushed the gpl/738-zedtokens-4 branch from dcd42e3 to ea0acbf Compare October 10, 2023 12:58
@geropl geropl changed the title [WIP] zedtokens 4 ZedTokens: SpiceDBAuthorizer cleanup Oct 10, 2023
@geropl geropl marked this pull request as ready for review October 11, 2023 06:33
@geropl geropl requested a review from a team as a code owner October 11, 2023 06:33
await this.tokenCache.set(
...updates.map<ZedTokenCacheKV>((u) => [
u.relationship?.resource,
writtenAt, // Make sure that in case we don't get a writtenAt token here, we at least invalidate the cache
Copy link
Contributor

Choose a reason for hiding this comment

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

I would always expect a token on successful writes. Did you see cases where no writtenAt was returned?

Copy link
Member Author

Choose a reason for hiding this comment

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

The API gives no guarantee, so I decided to not assume things. 🤷

Copy link
Contributor

Choose a reason for hiding this comment

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

I doubt it happens, but let's at least log a warning in those cases

// following https://github.com/authzed/spicedb/blob/786555c24af98abfe3f832c94dbae5ca518dcf50/pkg/zedtoken/zedtoken.go#L64-L100
const decodedBytes = base64decode(token);
const decodedToken = DecodedZedToken.decode(Buffer.from(decodedBytes, "utf8")).v1;
if (!decodedToken) {
Copy link
Contributor

Choose a reason for hiding this comment

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

is that not an error case?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, this is a technical error. But it would not break in a user-facing way - except we got a bunch of these, which we need to detect via metrics+alerts.

I think we need to decide (and document) how we see log levels being used, because I heart people (over time) argue for very different perspectives. 👍

Copy link
Contributor

Choose a reason for hiding this comment

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

Probably similar case to the above. I think we should at least log an error

}

type ZedTokenCacheKV = [objectRef: v1.ObjectReference | undefined, token: string | undefined];
interface ZedTokenCache {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think there's a need for an interface

Copy link
Member Author

Choose a reason for hiding this comment

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

I did not touch the code here yet. Let's do the rollout first.

export class RequestLocalZedTokenCache implements ZedTokenCache {
constructor() {}

async get(objectRef: v1.ObjectReference | undefined): Promise<string | undefined> {
Copy link
Contributor

Choose a reason for hiding this comment

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

none of these methods need to be async

Copy link
Contributor

Choose a reason for hiding this comment

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

Also let's remove the unused arguments. We can introduce them when we need them

Copy link
Member Author

Choose a reason for hiding this comment

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

I'd rather go with the current version and get data. 🙂 Removal is very quick.

Copy link
Contributor

Choose a reason for hiding this comment

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

I thought the reason for this PR is clean up?

return getContext().zedToken?.token;
}

async set(...kvs: ZedTokenCacheKV[]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

wouldn't it be enough to just pass in a single token and only set it if it is greater than the existing one?

Copy link
Member Author

Choose a reason for hiding this comment

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

We get a bunch of tokens in some cases. As mentioned above, happy to remove all of this once we decided the current implementation is sufficient.

Copy link
Contributor

Choose a reason for hiding this comment

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

only because you want to update them per resource which we currently don't do/need

}
}

async consistency(resourceRef: v1.ObjectReference | undefined): Promise<v1.Consistency> {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: I would pass in the zedtoken and move this method to the authorizer. it seems unrelated to the caching aspect.

Copy link
Member Author

Choose a reason for hiding this comment

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

For this cache implementation: Yes. For others definitely not. Again, happy to remove/fold in if we don't need that stuff. 🤞

Copy link
Contributor

@svenefftinge svenefftinge left a comment

Choose a reason for hiding this comment

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

Looks good!

(minus the comments regarding the token cache, which we can tackle in a follow up)

@geropl
Copy link
Member Author

geropl commented Oct 11, 2023

/unhold

@roboquat roboquat merged commit 9bde303 into main Oct 11, 2023
@roboquat roboquat deleted the gpl/738-zedtokens-4 branch October 11, 2023 07:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants