Skip to content

Commit b5d02e9

Browse files
authored
[SS-69] Add a GCP Connection to hold Google service account creds (#36694)
This PR brings on `gcp_auth` as a dependency. _stacked on #36693_
1 parent 4160cef commit b5d02e9

18 files changed

Lines changed: 341 additions & 14 deletions

File tree

Cargo.lock

Lines changed: 86 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -347,6 +347,7 @@ futures = "0.3.32"
347347
futures-core = "0.3.32"
348348
futures-task = "0.3.32"
349349
futures-util = "0.3.32"
350+
gcp_auth = "0.12.6"
350351
glob = "0.3.3"
351352
globset = "0.4.18"
352353
governor = "0.10.1"

deny.toml

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,19 @@ skip = [
130130
{ name = "hashbrown", version = "0.16.1" },
131131
# Used by dynfmt; iceberg/typetag pulls in v0.4.
132132
{ name = "erased-serde", version = "0.3.26" },
133+
# gcp_auth → hyper-rustls → rustls-native-certs pulls newer versions
134+
# while native-tls still pulls older versions.
135+
{ name = "core-foundation", version = "0.10.1" },
136+
{ name = "security-framework", version = "3.7.0" },
137+
{ name = "openssl-probe", version = "0.2.1" },
138+
# reqsign (via iceberg-storage-opendal / opendal) pins older deps
139+
# than the workspace.
140+
{ name = "jsonwebtoken", version = "9.3.1" },
141+
{ name = "quick-xml", version = "0.37.5" },
142+
# aws-lc-rs (via jsonwebtoken 10) and ring pull different `untrusted`.
143+
{ name = "untrusted", version = "0.7.1" },
144+
# Held back by lazy_static 1.4.0 (used by num-bigint-dig).
145+
{ name = "spin", version = "0.5.2" },
133146
]
134147

135148
[[bans.deny]]
@@ -206,9 +219,11 @@ wrappers = [
206219
]
207220

208221
# We prefer the system's native TLS or OpenSSL to Rustls, since they are more
209-
# mature and more widely used.
222+
# mature and more widely used. `gcp_auth` only ships with rustls-based TLS,
223+
# so allow it through.
210224
[[bans.deny]]
211225
name = "rustls"
226+
wrappers = ["hyper-rustls", "tokio-rustls"]
212227

213228
# once_cell is going to be added to std, and doesn't use macros
214229
# Unfortunately, its heavily used, so we have lots of exceptions.
@@ -219,6 +234,7 @@ wrappers = [
219234
"findshlibs",
220235
"launchdarkly-server-sdk",
221236
"launchdarkly-server-sdk-evaluation",
237+
"num-bigint-dig",
222238
"prometheus",
223239
"rayon-core",
224240
"sharded-slab",

src/adapter/src/catalog/builtin_table_updates.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -937,6 +937,7 @@ impl CatalogState {
937937
}
938938
ConnectionDetails::Csr(_)
939939
| ConnectionDetails::GlueSchemaRegistry(_)
940+
| ConnectionDetails::Gcp(_)
940941
| ConnectionDetails::Postgres(_)
941942
| ConnectionDetails::MySql(_)
942943
| ConnectionDetails::SqlServer(_)

src/adapter/src/catalog/state.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2776,6 +2776,7 @@ impl ConnectionResolver for CatalogState {
27762776
Ssh(conn) => Ssh(conn),
27772777
Aws(conn) => Aws(conn),
27782778
AwsPrivatelink(conn) => AwsPrivatelink(conn),
2779+
Gcp(conn) => Gcp(conn),
27792780
MySql(conn) => MySql(conn.into_inline_connection(self)),
27802781
SqlServer(conn) => SqlServer(conn.into_inline_connection(self)),
27812782
IcebergCatalog(conn) => IcebergCatalog(conn.into_inline_connection(self)),

src/adapter/src/coord/ddl.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1140,6 +1140,7 @@ impl Coordinator {
11401140
| ConnectionDetails::GlueSchemaRegistry(_)
11411141
| ConnectionDetails::Ssh { .. }
11421142
| ConnectionDetails::Aws(_)
1143+
| ConnectionDetails::Gcp(_)
11431144
| ConnectionDetails::IcebergCatalog(_) => {}
11441145
},
11451146
CatalogItem::Table(_) => {
@@ -1316,6 +1317,7 @@ impl Coordinator {
13161317
| ConnectionDetails::GlueSchemaRegistry(_)
13171318
| ConnectionDetails::Ssh { .. }
13181319
| ConnectionDetails::Aws(_)
1320+
| ConnectionDetails::Gcp(_)
13191321
| ConnectionDetails::IcebergCatalog(_) => {}
13201322
}
13211323
}

src/adapter/src/coord/sequencer/inner.rs

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ use mz_repr::{
4343
CatalogItemId, Datum, Diff, GlobalId, RelationVersion, RelationVersionSelector, Row, RowArena,
4444
RowIterator, Timestamp,
4545
};
46+
use mz_secrets::SecretsReader;
4647
use mz_sql::ast::{
4748
AlterSourceAddSubsourceOption, CreateSinkOption, CreateSinkOptionName, CreateSourceOptionName,
4849
CreateSubsourceOption, CreateSubsourceOptionName, SqlServerConfigOption,
@@ -63,6 +64,7 @@ use mz_sql::plan::{
6364
StatementContext,
6465
};
6566
use mz_sql::pure::{PurifiedSourceExport, generate_subsource_statements};
67+
use mz_storage_types::connections::gcp::GcpServiceAccountKeyTokenUri;
6668
use mz_storage_types::sinks::StorageSinkDesc;
6769
// Import `plan` module, but only import select elements to avoid merge conflicts on use statements.
6870
use mz_sql::plan::{
@@ -662,6 +664,19 @@ impl Coordinator {
662664
}
663665
self.caching_secrets_reader.invalidate(connection_id);
664666
}
667+
ConnectionDetails::Gcp(gcp) => {
668+
// A service account key defines its own OAuth2 token URI.
669+
// We only want to send requests to the actual Google OAuth2 token API,
670+
// so we inspect the key as early as we can.
671+
if let Err(err) = self
672+
.caching_secrets_reader
673+
.read_string(gcp.credentials_json)
674+
.await
675+
.and_then(|json| GcpServiceAccountKeyTokenUri::validate_json(&json))
676+
{
677+
return ctx.retire(Err(err.into()));
678+
}
679+
}
665680
_ => (),
666681
};
667682

src/sql-lexer/src/keywords.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
Abort
2727
Access
28+
Account
2829
Action
2930
Add
3031
Added
@@ -200,6 +201,7 @@ Full
200201
Fullname
201202
Function
202203
Fusion
204+
Gcp
203205
Generator
204206
Glue
205207
Grant

src/sql-parser/src/ast/defs/ddl.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -792,6 +792,7 @@ pub enum ConnectionOptionName {
792792
Scope,
793793
SecretAccessKey,
794794
SecurityProtocol,
795+
ServiceAccountKey,
795796
ServiceName,
796797
SshTunnel,
797798
SslCertificate,
@@ -836,6 +837,7 @@ impl AstDisplay for ConnectionOptionName {
836837
ConnectionOptionName::Scope => "SCOPE",
837838
ConnectionOptionName::SecurityProtocol => "SECURITY PROTOCOL",
838839
ConnectionOptionName::SecretAccessKey => "SECRET ACCESS KEY",
840+
ConnectionOptionName::ServiceAccountKey => "SERVICE ACCOUNT KEY",
839841
ConnectionOptionName::ServiceName => "SERVICE NAME",
840842
ConnectionOptionName::SshTunnel => "SSH TUNNEL",
841843
ConnectionOptionName::SslCertificate => "SSL CERTIFICATE",
@@ -886,6 +888,7 @@ impl WithOptionName for ConnectionOptionName {
886888
| ConnectionOptionName::Scope
887889
| ConnectionOptionName::SecurityProtocol
888890
| ConnectionOptionName::SecretAccessKey
891+
| ConnectionOptionName::ServiceAccountKey
889892
| ConnectionOptionName::ServiceName
890893
| ConnectionOptionName::SshTunnel
891894
| ConnectionOptionName::SslCertificate
@@ -915,6 +918,7 @@ pub enum CreateConnectionType {
915918
Aws,
916919
AwsPrivatelink,
917920
GlueSchemaRegistry,
921+
Gcp,
918922
Kafka,
919923
Csr,
920924
Postgres,
@@ -933,6 +937,7 @@ impl CreateConnectionType {
933937
Self::Aws => "aws",
934938
Self::AwsPrivatelink => "aws-privatelink",
935939
Self::GlueSchemaRegistry => "glue-schema-registry",
940+
Self::Gcp => "gcp",
936941
Self::Ssh => "ssh-tunnel",
937942
Self::MySql => "mysql",
938943
Self::SqlServer => "sql-server",
@@ -962,6 +967,9 @@ impl AstDisplay for CreateConnectionType {
962967
Self::GlueSchemaRegistry => {
963968
f.write_str("AWS GLUE SCHEMA REGISTRY");
964969
}
970+
Self::Gcp => {
971+
f.write_str("GCP");
972+
}
965973
Self::Ssh => {
966974
f.write_str("SSH TUNNEL");
967975
}

0 commit comments

Comments
 (0)