This is a micro service that implement the V4 signing process with Cloud Storage tools on Google Cloud Function. You don't need to write the signing process in you program. Just call this Sign Storage Url API after you deploy to google cloud function.
Environment Varibale | Required | Description |
---|---|---|
SERVICE_JSON_FILE | required | This is a key for signing storage. see [Get Signed Url Key](#Get Signed Url Key) |
BUCKET_NAME | optional | Add the multiple buckets separated by colon : to your white lists or leave blank for all buckets. |
Create a Google Cloud Project from here and set on terminal.
export ProjectID=<project_id>
# Set Project ID
gcloud config set project ${ProjectID}
You can change the storage location and default storage class.
export BucketName=<bucket_name>
# Create Bucket
gsutil mb -b on -c Standard -p ${ProjectID} -l asia gs://${BucketName}
After running the commands below, you will get the signed-url-key.json file under the current folder. You will need it on the next step.
# Create Service Account
gcloud iam service-accounts create "signed-url" --display-name "signed-url"
# Grant Service Account with storage object admin
gcloud projects add-iam-policy-binding ${ProjectID} \
--member serviceAccount:signed-url@${ProjectID}.iam.gserviceaccount.com \
--role roles/storage.objectAdmin
# Create Key
gcloud iam service-accounts keys create signed-url-key.json --iam-account signed-url@${ProjectID}.iam.gserviceaccount.com
Varibale | Required | Description |
---|---|---|
bucket | required | The bucket you want to access. You are able to skip this variable if there is only one bucket name in BUCKET_NAME. |
method | required | What action you want to process. |
object | required | The file name you want to access. |
time | optional | How much time (minute) the sign url is valid. 15 minutes is default value. |
gcloud functions deploy sign --entry-point=SignedUrl --runtime=go111 --trigger-http --quiet \
--set-env-vars SERVICE_JSON_FILE=signed-url-key.json
Testing
You can get the signed url from running the following command
curl -k -X POST -F "bucket=<bucket-name>" -F "method=POST" -F "object=hello.txt" https://<gcloud-function-url>/sign
Add the optional time:
curl -k -X POST -F "bucket=<bucket-name>" -F "method=POST" -F "object=hello.txt" -F "time=30" https://<gcloud-function-url>/sign
If you want to contraint which bucket is allowed to access, adding the BUCKET_NAME variable spliting each bucket with colon :
# multiple buckets
gcloud functions deploy sign --entry-point=SignedUrl --runtime=go111 --trigger-http --quiet \
--set-env-vars SERVICE_JSON_FILE=signed-url-key.json,BUCKET_NAME=<bucket-name1>:<bucket-name2>
Testing
You can get the signed url from running the following command
curl -k -X POST -F "bucket=<bucket-name>" -F "method=POST" -F "object=hello.txt" https://<gcloud-function-url>/sign
gcloud functions deploy sign --source=src --entry-point=SignedUrl --runtime=go113 --trigger-http --quiet \
--set-env-vars SERVICE_JSON_FILE=signed-url-key.json,BUCKET_NAME=<bucket-name1>
Testing
You can ignore bucket form data if you depoly a single storage bucket
curl -k -X POST -F "method=POST" -F "object=hello.txt" https://<gcloud-function-url>/sign
This key can be used in CI/CD.
Grant the Required permission:
- roles/iam.serviceAccountUser: Can act as the service account to start a Google Cloud Function.
- roles/cloudfunctions.developer: Deploy to Google Cloud Function
- roles/storage.admin: Create or delete a storage, and sign the storage url
# Create Service Account
gcloud iam service-accounts create "deploy-app" --display-name "deploy-app"
# Grant Service Account with cloud functions developer for deploy
gcloud projects add-iam-policy-binding ${ProjectID} \
--member serviceAccount:deploy-app@${ProjectID}.iam.gserviceaccount.com \
--role roles/iam.serviceAccountUser
gcloud projects add-iam-policy-binding ${ProjectID} \
--member serviceAccount:deploy-app@${ProjectID}.iam.gserviceaccount.com \
--role roles/cloudfunctions.developer
gcloud projects add-iam-policy-binding ${ProjectID} \
--member serviceAccount:deploy-app@${ProjectID}.iam.gserviceaccount.com \
--role roles/storage.admin
# Create Key
gcloud iam service-accounts keys create deploy-key.json --iam-account deploy-app@${ProjectID}.iam.gserviceaccount.com
import "github.com/akiirobot/sign-storage-url/src/sign"
url, err := sign.Sign(serviceAccount, whiteListBucket, objectName, method, bucket, timeStamp)
if err != nil {
log.Fatalln(err)
http.Error(w, "403 - Status Forbidden - " + err.Error(), http.StatusForbidden)
}