Skip to main content

Deployment scenarios

Where the consumer runs decides how it reaches the database — and that depends on the backend, not only on the consumer.

Aurora databases are not publicly accessible. Their endpoints are public DNS names resolving to private addresses, so a consumer needs a network path into the VPC. Two topologies are supported, and only two: the consumer runs in the Depot VPC, or it reaches the database through a PrivateLink interface endpoint. A third shape, tunnelling via the bastion, exists for development only.

Snowflake needs none of this — see Snowflake below. Sections 1 to 3 are about Aurora.

What every consumer needs​

Common requirements — every caller needs these, regardless of location type:

RequirementWhy
lambda:InvokeFunction on depot-<envId>-storage-locatorto resolve at all
Ambient AWS credentialsto sign the request, and to authenticate to whatever the resolved credential points at

Per location type — additional requirements beyond the common ones:

Location typeBeyond the common requirements
Aurorards-db:connect on the database resource (the token is signed locally; the permission needs no API call to check); trust for the RDS certificate (TLS is required)
SnowflakeNone, if using an alternate credential (a personal access token, externalbrowser SSO, or similar — see Client integration). If reading the resolved secret, secretsmanager:GetSecretValue (+ kms:Decrypt if the secret uses a CMK) scoped to that credential secret only
S3 TablesNone fixed here — authorisation was settled at deploy time by the dataset's own grant (directReadPrincipals / directWritePrincipals, or a Lake Formation grant for the Glue route) and depends on which route the caller uses; see the dataset/Iceberg-interop docs for the route-specific permissions

1. Inside the database's VPC​

The simplest case, and the one production should aim for.

Reachability comes back as DIRECT. Nothing beyond the baseline permissions is needed — just a route and a security-group rule permitting 5432. Sending callerVpcId is harmless here: the Locator recognises its own VPC and answers DIRECT without looking for an endpoint.

note

Other network paths — VPC peering, a transit gateway — are not supported topologies for Depot consumers. They may happen to work, but the Locator cannot see routing, so it would find no interface endpoint and answer REQUIRES_TUNNEL. If you are in that position, omit callerVpcId and use the canonical endpoint.

The supported way to reach the database from outside the Depot VPC: an interface endpoint in the consumer's own VPC, tagged with the database's canonical hostname.

The consumer must tell the Locator which VPC it is in, via callerVpcId, when that VPC is not the database's. The Locator then looks for an interface endpoint in that VPC tagged with the database's canonical hostname, and returns its DNS name in underlyingUrl. Read the VPC id from instance metadata rather than configuring it by hand:

http://169.254.169.254/latest/meta-data/network/interfaces/macs/<mac>/vpc-id

That needs no IAM permission. Sending it is harmless when you are in the database's VPC — the Locator recognises its own VPC and answers DIRECT without looking for an endpoint.

caution

Do not send callerVpcId if you reach the database by VPC peering or transit routing. Routing is invisible to the Locator, so it can only conclude that no interface endpoint bridges your VPC and answer REQUIRES_TUNNEL — when a direct connection would have worked. Omit it and you get the canonical endpoint.

Two things the Locator cannot supply: the interface endpoint itself, and the security-group rules reaching it. Both are environment provisioning. If no matching endpoint exists, the answer is REQUIRES_TUNNEL with the canonical endpoint — the Locator reports the gap rather than failing, leaving the caller to decide.

note

The canonicalEndpoint in the response is unchanged in every scenario. It, and not the host actually connected to, is what an IAM token must be signed against. See Client integration.

3. A developer's laptop — development only​

No VPC, no route. The connection has to be tunnelled through the environment's bastion using SSM port forwarding.

Here the client needs two permissions the other scenarios do not:

Extra requirementWhy
ssm:StartSession (and ssm:TerminateSession)to open the port-forwarding session
AWS CLI v2 and the Session Manager plugin on PATHthe tunnel is a local subprocess

ec2:DescribeInstances is not needed: pass needsBastionHint: true and the Locator returns bastionInstanceId, having looked the instance up by tag on the caller's behalf.

What stays with the client is running the tunnel — necessarily, since the local port is chosen locally and cannot be known by the Locator. So with reachability: 'REQUIRES_TUNNEL', treat underlyingUrl's host and port as placeholders and substitute the tunnel's local end, while leaving connectionProperties untouched.

warning

This path is for development. Production compute should be reachable without a tunnel — scenario 1 by preference, scenario 2 where accounts or VPCs genuinely differ.

Snowflake: no VPC required​

A Snowflake account is a public endpoint, so none of the machinery above applies. A consumer needs outbound internet access and nothing else: no VPC placement, no interface endpoint, no bastion, no rds-db:connect.

Consequences that differ from Aurora:

  • reachability is always DIRECT, and callerVpcId has no effect.
  • bastionInstanceId is never returned, even when asked for — a bastion exists to reach a database inside a VPC.
  • A credential does not cross the wire. The envelope carries a pointer (credential.kind === 'SECRETS_MANAGER', credential.secretArn), not a secret — unlike Aurora's locally-minted token, which never touches Secrets Manager at all. The secret only crosses the wire if and when the caller fetches it directly from Secrets Manager, at which point it is exactly as sensitive as before. See the permissions table above for what that costs.
  • sfUrl embeds the Snowflake account's region, which is not necessarily your AWS region.