You are viewing the documentation for Deno DeployEA. Looking for Deploy Classic documentation? View it here.
Deno DeployEA allows you to connect to cloud providers like AWS and Google Cloud Platform (GCP) without needing to manually manage static credentials. This is done through the use of OpenID Connect (OIDC) and identity federation.
Deno DeployEA is an OIDC provider. Every running application of Deno DeployEA can be issued short-lived JWT tokens that are signed by Deno DeployEA. These tokens contain information about the application, such as the organization and application ids and slugs, the context in which an application is executing, and the running revision ID.
By sending these tokens to AWS or GCP, one can exchange them for short-lived AWS or GCP credentials that can be used to access cloud resources such as AWS S3 buckets or Google Cloud Spanner instances. When sending the token to AWS or GCP, the token is verified by the cloud provider, which checks that it was issued by Deno DeployEA and that it is valid for the application and context that should be allowed to access the cloud resources.
To enable AWS or GCP to exchange OIDC tokens for credentials, the cloud provider needs to be configured to trust Deno DeployEA as an OIDC identity provider, and an AWS IAM role or GCP service account needs to be created that allows the exchange of tokens for credentials, for a specific Deno DeployEA application.
This guide contains three guides for setting up these AWS resources. You can use any of these to set up the AWS resources.
deno deploy setup-aws command from your local machine (recommended)aws CLITo set up AWS with Deno DeployEA, the following resources need to be created inside of your AWS account:
https://oidc.deno.com.sts.amazonaws.com.{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::<account-id>:oidc-provider/oidc.deno.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.deno.com:aud": "sts.amazonaws.com",
"oidc.deno.com:sub": "deployment:<organization-slug>/<application-slug>/<context-name>"
}
}
}
]
}
After setting up the AWS resources, navigate to the AWS cloud integration setup page from the app settings. There you must select the context(s) in which the cloud connection should be available.
Then you must enter the ARN (Amazon Resource Name) for the AWS IAM Role created earlier. After entering the ARN you can start a connection test by pressing the "Test connection" button. The connection test will check that the AWS IAM Role and OIDC provider are configured correctly, and does not allow access from apps, orgs, or contexts that should not have access.
After testing the connection, you can save the cloud connection.
After setting up a cloud connection between AWS and Deno DeployEA you can access AWS resources such as S3 directly from your application code, without having to configure any credentials.
The AWS SDK v3 automatically picks up on the cloud connection configuration. Here is an example of accessing an S3 bucket from a Deno DeployEA application with a configured AWS account.
import { ListBucketsCommand, S3Client } from "@aws-sdk/client-s3";
const s3 = new S3Client({ region: "us-west-2" });
Deno.serve(() => {
const { Buckets } = await s3.send(new ListBucketsCommand({}));
return Response.json(Buckets);
});
To set up GCP with Deno DeployEA, the following resources need to be created inside of your GCP account:
https://oidc.deno.com.https://iam.googleapis.com).google.subject = assertion.subattribute.full_slug = assertion.org_slug + "/" + assertion.app_slugroles/iam.workloadIdentityUser). Examples: principal://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/oidc-deno-com/subject/deployment:<ORG_SLUG>/<APP_SLUG>/<CONTEXT_NAME>
principalSet://iam.googleapis.com/projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/oidc-deno-com/attribute.full_slug/<ORG_SLUG>/<APP_SLUG>
This guide contains three guides for setting up these GCP resources. You can use any of these to set up the GCP resources.
deno deploy setup-gcp command from your local machine (recommended)gcloud CLIAfter setting up the GCP resources, navigate to the GCP cloud integration setup page from the app settings. There you must select the context(s) in which the cloud connection should be available.
Then you must enter the workload identity provider ID, in the form projects/<PROJECT_NUMBER>/locations/global/workloadIdentityPools/oidc-deno-com/providers/oidc-deno-com, and the email address of the GCP Service Account created earlier. After entering the email address you can start a connection test by pressing the "Test connection" button. The connection test will check that the GCP Service Account and OIDC provider are configured correctly, and does not allow access from apps, orgs, or contexts that should not have access.
After testing the connection, you can save the cloud connection.
After setting up a cloud connection between GCP and Deno DeployEA you can access GCP resources such as Cloud Storage directly from your application code, without having to configure any credentials.
The Google Cloud SDK automatically picks up on the cloud connection configuration. Here is an example of accessing a Cloud Storage bucket from a Deno DeployEA application with a configured GCP account.
import { Storage } from "@google-cloud/storage";
const storage = new Storage();
Deno.serve(() => {
const [buckets] = await storage.getBuckets();
return Response.json(buckets);
});
You can remove a cloud connection by pressing the "Delete" button in the cloud integration section, next to a specific cloud connection.
deno deploy setup-aws For instructions on how to set up AWS with Deno DeployEA using the deno deploy setup-aws command, please see the instructions on the AWS cloud integration setup page in your app settings.
aws CLI You can manually set up AWS resources using the AWS CLI. This requires having the AWS CLI installed and configured with appropriate permissions to create IAM roles, OIDC providers, and attach policies.
First, create the OIDC provider if it doesn't already exist:
aws iam create-open-id-connect-provider \
--url https://oidc.deno.com \
--client-id-list sts.amazonaws.com
Create a trust policy file that allows your Deno DeployEA application to assume the role. You can choose between allowing access to all contexts or specific contexts only.
For all contexts in your app:
# Create trust policy file for entire app
cat > trust-policy-all-contexts.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/oidc.deno.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringLike": {
"oidc.deno.com:sub": "deployment:YOUR_ORG/YOUR_APP/*"
}
}
}
]
}
EOF
For specific contexts only:
# Create trust policy file for specific contexts
cat > trust-policy-specific-contexts.json << EOF
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam::YOUR_ACCOUNT_ID:oidc-provider/oidc.deno.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.deno.com:sub": [
"deployment:YOUR_ORG/YOUR_APP/production",
"deployment:YOUR_ORG/YOUR_APP/staging"
]
}
}
}
]
}
EOF
Create the role using the appropriate trust policy:
# For entire app
aws iam create-role \
--role-name DenoDeploy-YourOrg-YourApp \
--assume-role-policy-document file://trust-policy-all-contexts.json
# OR for specific contexts
aws iam create-role \
--role-name DenoDeploy-YourOrg-YourApp \
--assume-role-policy-document file://trust-policy-specific-contexts.json
Attach the necessary policies to grant permissions for the AWS resources your application needs:
aws iam attach-role-policy \
--role-name DenoDeploy-YourOrg-YourApp \
--policy-arn arn:aws:iam::aws:policy/POLICY_NAME
Replace POLICY_NAME with the appropriate AWS policies (e.g., AmazonS3ReadOnlyAccess, AmazonDynamoDBReadOnlyAccess, etc.) based on your requirements.
After completing these steps, use the Role ARN in your Deno DeployEA cloud connection configuration.
You can set up AWS resources using the AWS Management Console web interface. This method provides a visual way to configure the necessary IAM resources.
https://oidc.deno.com
sts.amazonaws.com
oidc.deno.com)sts.amazonaws.com
Add a condition to restrict which Deno DeployEA applications can assume this role. Choose one approach:
For all contexts in your app:
oidc.deno.com:sub
StringLike
deployment:YOUR_ORG/YOUR_APP/*
For specific contexts only:
oidc.deno.com:sub
StringEquals
deployment:YOUR_ORG/YOUR_APP/production
Click "Next" to continue.
AmazonS3ReadOnlyAccess or AmazonS3FullAccess
AmazonDynamoDBReadOnlyAccess or AmazonDynamoDBFullAccess
DenoDeploy-YourOrg-YourApp (replace with your actual organization and app names)After creating the role:
arn:aws:iam::123456789012:role/DenoDeploy-YourOrg-YourApp)You can use Terraform to programmatically create the AWS resources needed for cloud connections. This approach is ideal for infrastructure-as-code workflows.
Create a Terraform configuration file with the following content:
# Variables
variable "org" {
description = "Deno Deploy organization name"
type = string
}
variable "app" {
description = "Deno Deploy app name"
type = string
}
variable "contexts" {
description = "List of specific contexts to allow (leave empty for all contexts)"
type = list(string)
default = []
}
# OIDC Provider
resource "aws_iam_openid_connect_provider" "deno_deploy" {
url = "https://oidc.deno.com"
client_id_list = ["sts.amazonaws.com"]
}
# IAM Role with dynamic trust policy based on contexts
resource "aws_iam_role" "deno_deploy_role" {
name = "DenoDeploy-${var.org}-${var.app}"
assume_role_policy = jsonencode({
Version = "2012-10-17"
Statement = [
{
Effect = "Allow"
Principal = {
Federated = aws_iam_openid_connect_provider.deno_deploy.arn
}
Action = "sts:AssumeRoleWithWebIdentity"
Condition = length(var.contexts) > 0 ? {
# Specific contexts only
StringEquals = {
"oidc.deno.com:sub" = [
for context in var.contexts : "deployment:${var.org}/${var.app}/${context}"
]
}
} : {
# All contexts (wildcard)
StringLike = {
"oidc.deno.com:sub" = "deployment:${var.org}/${var.app}/*"
}
}
}
]
})
}
# Attach policies
resource "aws_iam_role_policy_attachment" "example" {
role = aws_iam_role.deno_deploy_role.name
policy_arn = "arn:aws:iam::aws:policy/POLICY_NAME"
}
# Output the role ARN
output "role_arn" {
value = aws_iam_role.deno_deploy_role.arn
}
For entire app access (all contexts):
module "deno_deploy_aws" {
source = "./path-to-terraform-module"
org = "your-org"
app = "your-app"
contexts = [] # Empty list allows all contexts
}
For specific contexts only:
module "deno_deploy_aws" {
source = "./path-to-terraform-module"
org = "your-org"
app = "your-app"
contexts = ["production", "staging"]
}
Initialize Terraform:
terraform init
Plan the deployment:
terraform plan
Apply the configuration:
terraform apply
After applying, Terraform will output the Role ARN that you can use in your Deno DeployEA cloud connection configuration.
Replace POLICY_NAME in the aws_iam_role_policy_attachment resource with the appropriate AWS managed policies or create custom policies based on your requirements. You can add multiple policy attachments by creating additional aws_iam_role_policy_attachment resources.
deno deploy setup-gcp For instructions on how to set up GCP with Deno DeployEA using the deno deploy setup-gcp command, please see the instructions on the Google cloud integration setup page in your app settings.
gcloud CLI You can manually set up GCP resources using the gcloud CLI. This requires having the gcloud CLI installed and authenticated with appropriate permissions to create workload identity pools, service accounts, and grant IAM roles.
iam.googleapis.comiamcredentials.googleapis.comsts.googleapis.comFirst, enable the required APIs for your project:
gcloud services enable iam.googleapis.com
gcloud services enable iamcredentials.googleapis.com
gcloud services enable sts.googleapis.com
Create a workload identity pool to manage external identities:
gcloud iam workload-identity-pools create oidc-deno-com \
--location=global \
--display-name="Deno Deploy Workload Identity Pool"
Configure the OIDC provider within the workload identity pool:
gcloud iam workload-identity-pools providers create-oidc oidc-deno-com \
--workload-identity-pool=oidc-deno-com \
--location=global \
--issuer-uri=https://oidc.deno.com \
--attribute-mapping="google.subject=assertion.sub,attribute.org_slug=assertion.org_slug,attribute.app_slug=assertion.app_slug,attribute.full_slug=assertion.org_slug+\"/\"+assertion.app_slug"
Create a service account that will be used by your Deno DeployEA application:
gcloud iam service-accounts create deno-your-org-your-app \
--display-name="Deno Deploy YourOrg/YourApp"
Get your project number and configure the workload identity binding. Choose between allowing access to all contexts or specific contexts only.
# Get project number
PROJECT_NUMBER=$(gcloud projects describe PROJECT_ID --format="value(projectNumber)")
For all contexts in your app:
gcloud iam service-accounts add-iam-policy-binding \
deno-your-org-your-app@PROJECT_ID.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principalSet://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/attribute.full_slug/YOUR_ORG/YOUR_APP"
For specific contexts only:
# Bind for production context
gcloud iam service-accounts add-iam-policy-binding \
deno-your-org-your-app@PROJECT_ID.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/subject/deployment:YOUR_ORG/YOUR_APP/production"
# Bind for staging context
gcloud iam service-accounts add-iam-policy-binding \
deno-your-org-your-app@PROJECT_ID.iam.gserviceaccount.com \
--role=roles/iam.workloadIdentityUser \
--member="principal://iam.googleapis.com/projects/$PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/subject/deployment:YOUR_ORG/YOUR_APP/staging"
# Add more bindings for each specific context as needed
Grant the necessary roles to the service account for accessing GCP resources:
gcloud projects add-iam-policy-binding PROJECT_ID \
--member="serviceAccount:deno-your-org-your-app@PROJECT_ID.iam.gserviceaccount.com" \
--role="roles/ROLE_NAME"
Replace ROLE_NAME with appropriate roles such as:
roles/storage.objectViewer for Cloud Storage read accessroles/storage.objectAdmin for Cloud Storage full accessroles/cloudsql.client for Cloud SQL accessAfter completing the setup, you'll need two values for your Deno DeployEA configuration:
projects/PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/providers/oidc-deno-com
deno-your-org-your-app@PROJECT_ID.iam.gserviceaccount.com
Use these values in your Deno DeployEA cloud connection configuration.
You can set up GCP resources using the Google Cloud Console web interface. This method provides a visual way to configure workload identity federation and service accounts.
Deno Deploy Workload Id Pool
oidc-deno-com
Add a provider:
Deno Deploy OIDC Provider
oidc-deno-com
https://oidc.deno.com
Configure attribute mappings:
google.subject → assertion.sub
attribute.org_slug → assertion.org_slug
attribute.app_slug → assertion.app_slug
attribute.full_slug → assertion.org_slug + "/" + assertion.app_slug
Click "Save"
deno-your-org-your-app
deno-your-org-your-app
Service account for Deno Deploy project your-org/your-app
Storage Object Viewer or Storage Admin
Cloud SQL Client
Go back to the created service account
Click on the "Principals with access" tab
Click "Grant Access"
Configure principals - choose one approach:
For all contexts in your app:
principalSet://iam.googleapis.com/projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/attribute.full_slug/YOUR_ORG/YOUR_APP
For specific contexts only:
principal://iam.googleapis.com/projects/YOUR_PROJECT_NUMBER/locations/global/workloadIdentityPools/oidc-deno-com/subject/deployment:YOUR_ORG/YOUR_APP/production
Role: Workload Identity User
Click "Save"
You'll need two values for your Deno DeployEA configuration:
projects/)The final workload identity pool overview should show:
Use the Service Account Email and Workload Provider ID in your Deno DeployEA cloud connection configuration.
You can use Terraform to programmatically create the GCP resources needed for cloud connections. This approach is ideal for infrastructure-as-code workflows.
Create a Terraform configuration file with the following content:
# Variables
variable "org" {
description = "Deno Deploy organization name"
type = string
}
variable "app" {
description = "Deno Deploy app name"
type = string
}
variable "contexts" {
description = "List of specific contexts to allow (leave empty for all contexts)"
type = list(string)
default = []
}
variable "project_id" {
description = "GCP Project ID"
type = string
}
variable "roles" {
description = "List of IAM roles to grant to the service account"
type = list(string)
default = []
}
# Data source for project information
data "google_project" "project" {
project_id = var.project_id
}
# Workload Identity Pool
resource "google_iam_workload_identity_pool" "deno_deploy" {
workload_identity_pool_id = "oidc-deno-com"
display_name = "Deno Deploy Workload Id Pool"
}
# Workload Identity Provider
resource "google_iam_workload_identity_pool_provider" "deno_deploy" {
workload_identity_pool_id = google_iam_workload_identity_pool.deno_deploy.workload_identity_pool_id
workload_identity_pool_provider_id = "oidc-deno-com"
display_name = "Deno Deploy OIDC Provider"
attribute_mapping = {
"google.subject" = "assertion.sub"
"attribute.org_slug" = "assertion.org_slug"
"attribute.app_slug" = "assertion.app_slug"
"attribute.full_slug" = "assertion.org_slug + \"/\" + assertion.app_slug"
}
oidc {
issuer_uri = "https://oidc.deno.com"
}
}
# Service Account
resource "google_service_account" "deno_deploy" {
account_id = "deno-${var.org}-${var.app}"
display_name = "Deno Deploy ${var.org}/${var.app}"
}
# Workload Identity Binding - dynamic based on contexts
resource "google_service_account_iam_binding" "workload_identity" {
service_account_id = google_service_account.deno_deploy.name
role = "roles/iam.workloadIdentityUser"
members = length(var.contexts) > 0 ? [
# Specific contexts only
for context in var.contexts :
"principal://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.deno_deploy.workload_identity_pool_id}/subject/deployment:${var.org}/${var.app}/${context}"
] : [
# All contexts (using attribute mapping)
"principalSet://iam.googleapis.com/projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.deno_deploy.workload_identity_pool_id}/attribute.full_slug/${var.org}/${var.app}"
]
}
# Grant roles to service account
resource "google_project_iam_member" "service_account_roles" {
for_each = toset(var.roles)
project = var.project_id
role = each.value
member = "serviceAccount:${google_service_account.deno_deploy.email}"
}
# Outputs
output "workload_provider_id" {
value = "projects/${data.google_project.project.number}/locations/global/workloadIdentityPools/${google_iam_workload_identity_pool.deno_deploy.workload_identity_pool_id}/providers/${google_iam_workload_identity_pool_provider.deno_deploy.workload_identity_pool_provider_id}"
}
output "service_account_email" {
value = google_service_account.deno_deploy.email
}
For entire app access (all contexts):
module "deno_deploy_gcp" {
source = "./path-to-terraform-module"
org = "your-org"
app = "your-app"
project_id = "your-gcp-project-id"
contexts = [] # Empty list allows all contexts
roles = [
"roles/storage.objectViewer",
"roles/cloudsql.client"
]
}
For specific contexts only:
module "deno_deploy_gcp" {
source = "./path-to-terraform-module"
org = "your-org"
app = "your-app"
project_id = "your-gcp-project-id"
contexts = ["production", "staging"]
roles = [
"roles/storage.objectAdmin",
"roles/cloudsql.client"
]
}
Initialize Terraform:
terraform init
Plan the deployment:
terraform plan
Apply the configuration:
terraform apply
After applying, Terraform will output the Workload Provider ID and Service Account Email that you can use in your Deno DeployEA cloud connection configuration.
The roles variable accepts a list of GCP IAM roles. Common roles include:
roles/storage.objectViewer - Read access to Cloud Storageroles/storage.objectAdmin - Full access to Cloud Storage objectsroles/cloudsql.client - Access to Cloud SQL instancesroles/secretmanager.secretAccessor - Access to Secret Manager secrets
© 2018–2025 the Deno authors
Licensed under the MIT License.
https://docs.deno.com/deploy/early-access/reference/cloud-connections