Native Google authentication for GCS: service-account keys, Application Default Credentials and Workload Identity.
id:gcs- Capabilities:
{ directUrl: <computed>, contentTypeMetadata: true, streamingPut: true }
You may not need this package
With an HMAC key, the S3 adapter reaches GCS already. Use this one when HMAC keys are forbidden, or for Workload Identity.
Install
npm install @orthacms/media-provider-gcsConfigure
MEDIA_GCS_BUCKET=acme-cms-media
MEDIA_GCS_PROJECT_ID=acme-prod
MEDIA_GCS_KEY_FILE=/secrets/gcs-media.json
MEDIA_DIRECT_SERVE=signed-url MEDIA_GCS_BUCKET=acme-cms-media
# no key file: Application Default Credentials / Workload Identity
# sign URLs through IAM (needs iam.serviceAccounts.signBlob)
MEDIA_GCS_SIGN_WITH_IAM=true
MEDIA_DIRECT_SERVE=signed-url MEDIA_GCS_BUCKET=acme-cms-media
# no key, no IAM signing: downloads stream through the app
MEDIA_DIRECT_SERVE=off | Variable | Default | Notes |
|---|---|---|
MEDIA_GCS_BUCKET | required | |
MEDIA_GCS_PROJECT_ID | ADC’s project | |
MEDIA_GCS_KEY_FILE | unset | Service-account JSON key path |
MEDIA_GCS_SIGN_WITH_IAM | false | Sign via IAM signBlob instead of a private key |
Read by a generated app’s config/media-storage.ts (the reference server ships
with local disk):
import type { GcsStorageConfig } from '@orthacms/media-provider-gcs';
import { defined, readEnv, readFlag, requireEnv } from '@orthacms/utils-server';
export function mediaStorage(): GcsStorageConfig {
return defined({
bucket: requireEnv('MEDIA_GCS_BUCKET'),
projectId: readEnv('MEDIA_GCS_PROJECT_ID'),
keyFilename: readEnv('MEDIA_GCS_KEY_FILE'),
signWithIam: readFlag('MEDIA_GCS_SIGN_WITH_IAM', false)
});
}All options
GcsStorageConfig: bucket, projectId?, keyFilename?,
credentials? ({ client_email, private_key }), keyPrefix?,
signWithIam?, bucketClient? (a pre-built Bucket).
| How it authenticates | directUrl |
|---|---|
keyFilename or inline credentials | true |
signWithIam: true | true |
| Bare Application Default Credentials | false — proxied |
Register
// apps/server/src/plugins.ts
import { createGcsStorageProvider } from '@orthacms/media-provider-gcs';
MediaServerPlugin({
provider: createGcsStorageProvider(config.plugins.media.storage),
config: config.plugins.media
});Verify
verify() reads the bucket’s metadata at boot. A wrong bucket or a credential
that cannot see it refuses the start.
Grant the runtime service account access, then upload a file (curl example) and list it:
gcloud storage buckets add-iam-policy-binding gs://acme-cms-media \
--member=serviceAccount:cms@acme-prod.iam.gserviceaccount.com \
--role=roles/storage.objectAdmin
gcloud storage ls --recursive gs://acme-cms-media/
# gs://acme-cms-media/<workspaceId>/<assetId>/kingfisher.jpgWith signed-url, the download’s Location is a V4 signed URL carrying
response-content-disposition and response-content-type.
Behaviour worth knowing
getreads metadata before opening the stream, so a missing object is a 404 rather than a broken streaming 200.- A failed upload deletes the object.
signWithIamis opt-in because it needsiam.serviceAccounts.signBlob.