-
Notifications
You must be signed in to change notification settings - Fork 9
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
Add support for lazy certificate refresh #285
Comments
Hi @hessjcg, I'm just wondering if you'd be able to provide any indication of when this might be available please? This is currently blocking us adopting the connector because we deploy lots of cloud functions and the cost to always allocate the CPU for all our functions would be prohibitive. |
Hi @rstreefland! We just implemented this change in Java and Python, Node is up next on our list. We should be getting to it in the coming week or two. Once we do merge it, we will cut an immediate release to unblock you 😄 |
@jackwotherspoon Amazing, thank you! |
Hi @jackwotherspoon. Sorry to nag, but do you have an update on this one please? It's the last issue blocking us adopting this and IAM database authentication 🙏 |
@hessjcg will be the one working on this, he has had some higher priority things take precedence recently. He should be able to give a more accurate timeline of when he will get to this. Hopefully soon 😄 @rstreefland are you connecting over Public IP or Private IP to your Cloud SQL instance(s)? If you are connecting over Private IP I would recommend just connecting directly to the Private IP address (or DNS name if using PSC), it will give you reduced latency compared to using the Connector and I can even show you how to still get IAM database authentication with a direct connection. Let me know if this would help in the meantime. |
@jackwotherspoon We are connecting using Public IP currently, but could switch to Private IP if necessary. We're using Cloud Run and 2nd Generation Cloud Functions to serve our workloads and my current understanding is that IAM database authentication is not currently possible without using the connector? If you're able to share an alternative solution, that would be incredibly useful please. |
For Public IP, we recommend using a Connector or the Cloud SQL Proxy for the security benefits so that is valid.
While we haven't added these samples to our official Google Cloud docs (but we will be soon), for Private IP connections there is a way to do direct connections and configure IAM database authentication. Here is an example for Postgres using the const {Pool} = require('pg');
const {GoogleAuth} = require('google-auth-library');
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/sqlservice.login'],
});
const pool = new Pool({
host: '<Cloud SQL instance private ip>',
user: 'sa-name@project-id.iam',
password: async () => {
return await auth.getAccessToken();
},
database: 'mydb',
ssl: {
require: true,
rejectUnauthorized: false, // required for self-signed certs
// https://node-postgres.com/features/ssl#self-signed-cert
}
}); Essentially IAM database authentication boils down to using an IAM Principal's OAuth2 token as the database Hope this helps 😄 |
@jackwotherspoon Thanks for this. With this method, would the OAuth2 access token expiry need to be handled by my application code or does the node-postgres pool handle this? |
@rstreefland Great question! I believe the pool will hopefully recycle the connection if the token is expired but I'm not 100% sure if it will. You could guarantee a fresh token with a 3600s lifetime by creating a new This coupled with setting the const pool = new Pool({
host: '<Cloud SQL instance private ip>',
user: 'sa-name@project-id.iam',
password: async () => {
const auth = new GoogleAuth({
scopes: ['https://www.googleapis.com/auth/sqlservice.login'],
});
return await auth.getAccessToken();
},
database: 'mydb',
ssl: {
require: true,
rejectUnauthorized: false, // required for self-signed certs
// https://node-postgres.com/features/ssl#self-signed-cert
},
maxLifetimeSeconds: 2700 // 45 minutes
}); |
Hello all. Unfortunately this feature will not be available in the near future. The implementation is not as straightforward as we anticipated. The connector configures the database driver options to use the connector to create new sockets to the database. Currently, the Postgres and Mysql database drivers allow you to configure a function that returns a To summarize the code as-is today: const options = {
stream: function() {
const connectionInfo = Connector.getCachedConnectionInfo(instanceName)
return net.connect(connectionInfo.ipAddress)
}
} In order to make lazy refresh work, the connector would need to asynchronously check if the connection info is valid, loading it if needed, and then instantiate the const options = {
stream: async function() { // Not Allowed!
const connectionInfo = await Connector.getOrLoadConnectionInfo(instanceName)
return net.connect(connectionInfo.ipAddress)
}
} Unfortunately the Postgres and MySQL database drivers can't use an async function here. Also, we don't want to implement a busy-wait loop for the connectionInfo promise, as it would be anti-idiomatic. We are open to suggestions on how to implement this. |
When using the Connector in serverless environments where the CPU is throttled outside of request processing, the refresh cycle can break. This is a feature request to support a lazy refresh where the Connector retrieves a new certificate when the existing one is expired and a new connection attempt has started.
The text was updated successfully, but these errors were encountered: