Skip to content
This repository has been archived by the owner on Oct 18, 2023. It is now read-only.

Hrana server authentication #235

Merged
merged 2 commits into from
Feb 22, 2023
Merged

Hrana server authentication #235

merged 2 commits into from
Feb 22, 2023

Conversation

honzasp
Copy link
Contributor

@honzasp honzasp commented Feb 17, 2023

Implement authentication in Hrana using JWTs. An Ed25519 public key is passed to sqld using --hrana-jwt-key-file, and the received JWT is verified using this key. We ignore the claims, except by validating the expiration in exp.

I also added a helper script scripts/gen_jwt.py to generate the key and a JWT.

This PR is stacked on top of #231.

Comment on lines 55 to 75

pub fn load_jwt_key(path: &Path) -> Result<jsonwebtoken::DecodingKey> {
let data = fs::read(path)?;
if data.starts_with(b"-----BEGIN PUBLIC KEY-----") {
jsonwebtoken::DecodingKey::from_ed_pem(&data)
.context("Could not decode Ed25519 public key from PEM")
} else if data.starts_with(b"-----BEGIN PRIVATE KEY-----") {
bail!("Received a private key, but a public key is expected")
} else if data.starts_with(b"-----BEGIN") {
bail!("Key is in unsupported PEM format")
} else if let Ok(data_str) = str::from_utf8(&data) {
jsonwebtoken::DecodingKey::from_ed_components(&data_str)
.context("Could not decode Ed25519 public key from base64")
} else {
bail!("Key is in an unsupported binary format")
}
}
Copy link
Collaborator

@MarinPostma MarinPostma Feb 17, 2023

Choose a reason for hiding this comment

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

This code would certainly be useful in the auth mod!

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The code in http/auth.rs seems to implement a diferent mechanism, instead of passing an argument pointing to a file with Ed25519 pubkey, we pass an argument that directly contains a base64-encoded RSA pubkey in PKCS#8 (which is awkwardly decoded by wrapping it in PEM headers and parsing it as PEM). However, the JWT auth in HTTP is not yet used in Turso, so perhaps we can use the Hrana mechanism also in HTTP?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Wait now that you mention it, I'm wondering if moving files to the deployed machines is desirable? It's probably easier to pass this value as an environment variable on provisioning

Copy link
Collaborator

Choose a reason for hiding this comment

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

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We do a similar thing with TLS certificates and keys for gRPC: they are passed as env variables to the container and the entrypoint script stores them in temporary files and passes the paths to these files to sqld via the command line arguments.

Now that I think about it again, this is rather silly: it would be better if all keys/certs were passed to sqld in one of two ways:

  • With a command line argument pointing to a file (useful when you run sqld standalone)
  • With an env variable containing the data (useful when you run sqld in a container)

However, I'm not sure how we could implement this scheme with clap?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe @CodingDoug and @athoscouto input would be useful here

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added the option of passing the key directly in env SQLD_HRANA_JWT_KEY, so we won't need to create temporary files in a container.

sqld/src/hrana/session.rs Outdated Show resolved Hide resolved
@honzasp honzasp force-pushed the hrana-auth branch 3 times, most recently from 141d78a to b7fbf40 Compare February 21, 2023 09:53
@honzasp honzasp changed the base branch from hrana-server to main February 21, 2023 09:53
@honzasp honzasp marked this pull request as ready for review February 21, 2023 09:54
@honzasp honzasp force-pushed the hrana-auth branch 3 times, most recently from cfbb62a to 7459d64 Compare February 22, 2023 09:08
@honzasp
Copy link
Contributor Author

honzasp commented Feb 22, 2023

bors merge

@bors
Copy link
Contributor

bors bot commented Feb 22, 2023

Merge conflict.

@honzasp
Copy link
Contributor Author

honzasp commented Feb 22, 2023

bors merge

@bors
Copy link
Contributor

bors bot commented Feb 22, 2023

Build succeeded:

@bors bors bot merged commit 332dd54 into libsql:main Feb 22, 2023
@honzasp honzasp deleted the hrana-auth branch February 27, 2023 10:10
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants