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

Proxy for accounts across PDSes #1724

Merged
merged 14 commits into from
Oct 13, 2023
Merged

Proxy for accounts across PDSes #1724

merged 14 commits into from
Oct 13, 2023

Conversation

devinivy
Copy link
Collaborator

@devinivy devinivy commented Oct 9, 2023

A few things going on here:

  • Switch from jsonwebtoken to jose library to support secp256k1 keys for asymmetric signing of JWTs.
  • Setup rudimentary proxy to route user to their home pds when applicable.
    • Will do a second pass on this in a separate PR to make the proxying lighterweight and more faithful (e.g. proper/full header passthrough).
  • Serve token expiration errors when account migrates across pdses.

Feature branch: #1722

Ref: #1742 for some practical usage.

@devinivy devinivy marked this pull request as ready for review October 12, 2023 21:37
if (!pds) {
throw new UpstreamFailureError('unknown pds')
}
// @TODO reuse agents
Copy link
Collaborator

Choose a reason for hiding this comment

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

yeah unfortunately this really is necessary

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

My plan is for this to go away when we incorporate #1730 😈


export class ServerAuth {
private _secret: string
private _signingSecret: KeyObject
private _signingKeyPromise?: Promise<KeyObject>
Copy link
Collaborator

Choose a reason for hiding this comment

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

i'm inclined to put this behind an async static constructor so we don't have to manage the promise


export type ServerAuthOpts = {
jwtSecret: string
jwtSigningKey?: crypto.Secp256k1Keypair
Copy link
Collaborator

Choose a reason for hiding this comment

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

is the intention to always support either symmetric or asymmetric? or just as a cutover period thing?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In my view it would be great to support both, but it's only for cutover that we need to support them at the same time / on the same server.

@@ -324,3 +361,13 @@ export enum AuthStatus {
Invalid,
Missing,
}

const createPrivateKeyObject = async (
Copy link
Collaborator

Choose a reason for hiding this comment

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

mer it's a shame we have to convert between these :/

If we need to use their key format, I don't think it'd be wrong to just set the config value as a pem/der formatted key 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Going to comment below in context of the multicodecs idea 👍

@@ -74,6 +74,9 @@ export const readEnv = (): ServerEnvironment => {

// secrets
jwtSecret: envStr('PDS_JWT_SECRET'),
jwtSigningKeyK256PrivateKeyHex: envStr(
'PDS_JWT_SIGNING_KEY_K256_PRIVATE_KEY_HEX',
Copy link
Collaborator

Choose a reason for hiding this comment

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

heh or we could do what bryan was pushing for & use multicodecs for our private keys to avoid stuff like this

could jam some multikey <> der utilities in @atproto/crypto

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I have a smattering of general thoughts on this, not sure how they work out together yet 🥴 😆

  • For the purposes of configuration I think it would be pretty nice to support PEMs since so much tooling works well with it, and it's familiar to people. Ideally we could accept something that openssl can spit out. It's possible that these env vars could become file paths to keys. Right now here's how keys are generated with common tools—not the end of the world, but feels like it could be better: https://github.com/bluesky-social/pds/blob/01dbd27728754dc765316e5e4a768380238bddc0/installer.sh#L16.
  • For the @atproto/crypto interfaces, I think it would be great in general to be able to convert to node's KeyObject interface and/or the webby CryptoKey / CryptoKeyPair interfaces (I lean towards the latter). Seems very desirable to me for interop purposes!
  • Just an observation: we'll also want to configure public keys on their own, e.g. the jwt verify key in Misc tests and fixes for entryway PDS #1742. Maybe we'll want a standard way to represent those in @atproto/crypto?

The multicodecs direction seems great for a ton of use-cases, but I'm not sure whether it's ideal for these app configurations. I might need to learn a little more about how it would work, though.

@@ -588,6 +595,15 @@ export class AccountService {
await this.db.db.insertInto('user_pref').values(putPrefs).execute()
}
}

// @TODO cache w/ in-mem lookup
async getPds(pdsDid: string) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

okay this is inspiring me to actually use the pdsDid in the mod refactor i did 😛

Copy link
Collaborator

@dholms dholms left a comment

Choose a reason for hiding this comment

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

lookin good 👍

@devinivy devinivy merged commit f7720d8 into multi-pds-auth Oct 13, 2023
10 checks passed
@devinivy devinivy deleted the multi-pds-auth-keys branch October 13, 2023 19:26
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.

2 participants