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

Read db config from environment #125

Merged
merged 10 commits into from
Nov 9, 2023
Merged

Read db config from environment #125

merged 10 commits into from
Nov 9, 2023

Conversation

wiltsecarpenter
Copy link
Contributor

@wiltsecarpenter wiltsecarpenter commented Nov 8, 2023

  • Read db config from environment variables
  • Set expiration time on db tokens

db config in environment is done by variables with names in the form:

OBSERVABLEHQ_DB_SECRET_mydbname=secret

This secret is obtained using the observablehq_database_proxy command using the --standalone option

Copy link
Member

@mbostock mbostock left a comment

Choose a reason for hiding this comment

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

Should we remove the existing readDatabaseProxyConfig (~/.observablehq) for now, and only look for the database token in process.env? I am inclined to provide fewer ways of doing something, and process.env is the preferred way of doing it in CI.

@wiltsecarpenter
Copy link
Contributor Author

Simplified, added test, removed reading of config file

Copy link
Member

@mbostock mbostock left a comment

Choose a reason for hiding this comment

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

Thanks for making the changes.

Ideally we would have a few more safeguards here: this checks that the environment variable exists, and that it’s base64-encoded JSON, but it doesn’t check that it’s an object, or that the specified fields are present, etc. In particular, we might especially want to check that the secret isn’t empty.

Maybe:

function parseSecret(value: string): DatabaseConfig {
  const obj = JSON.parse(Buffer.from(value, "base64").toString("utf8"));
  if (!obj || typeof obj !== "object") throw new Error("invalid database config");
  if (typeof obj.host !== "string") throw new Error("missing or invalid host");
  if (typeof obj.port !== "number") throw new Error("missing or invalid port");
 // etc.
  return obj;
}

Also given the new API, it seems like we could now just read the environment variable for the requested database, rather than needing to scan process.env for everything that starts with OBSERVABLEHQ_DB_SECRET_. That seems simpler to me, as we wouldn’t need to console.error and continue, only to throw an Error again later.

@wiltsecarpenter
Copy link
Contributor Author

Okay, further simplified

Copy link
Member

@mbostock mbostock 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 to me!

I think in the future we might want to split these into separate variables so that the values are more easily inspected by the user. The opaque base-64 string is difficult to verify. The Snowflake SDK, for example, uses a variety of fields that are typically fine being public:

  • SNOWFLAKE_ACCOUNT
  • SNOWFLAKE_DATABASE
  • SNOWFLAKE_ROLE
  • SNOWFLAKE_SCHEMA
  • SNOWFLAKE_USERNAME
  • SNOWFLAKE_WAREHOUSE

The only one that is private is:

  • SNOWFLAKE_PASSWORD

Our needs are complicated by wanting to support multiple databases, but that’s still addressable with a shared prefix.

@wiltsecarpenter
Copy link
Contributor Author

wiltsecarpenter commented Nov 9, 2023 via email

@wiltsecarpenter wiltsecarpenter merged commit 48c20d1 into main Nov 9, 2023
1 check passed
@wiltsecarpenter wiltsecarpenter deleted the wiltse/databases branch November 9, 2023 23:45
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.

makeCLIResolver should use environment variables for database client secrets, not a config file
2 participants