- 
                Notifications
    
You must be signed in to change notification settings  - Fork 1.8k
 
Description
Background
Affected Resource(s)
- google_compute_backend_bucket_signed_url_key
 
When creating a signed URL for CloudCDN, I used  random_id b64_url.
google_compute_backend_bucket_signed_url_key | Resources | hashicorp/google | Terraform Registry
resource "random_id" "url_signature" {
  byte_length = 16
}
resource "google_compute_backend_bucket_signed_url_key" "backend_key" {
  name           = "test-key"
  key_value      = random_id.url_signature.b64_url
  backend_bucket = google_compute_backend_bucket.test_backend.name
}I have confirmed that this works.
However, when I created them from the Google Cloud console or gcloud command, the keys created were URL safe, base64 encoded, and padded with =.
Furthermore, the official Google Cloud sample code assumes padded keys, so I could not use the keys created with b64_url without modification. In addition, when I tried to create a signed URL using the gcloud compute sign-url command, an error occurred because it used a key without padding.
failed gcloud command
> gcloud compute sign-url \
  "https://example.com/test.png" \
  --key-name test-key \
  --key-file key-file \
  --expires-in 5m \
  --validate
ERROR: gcloud crashed (Error): Incorrect padding
If you would like to report this issue, please run the following command:
  gcloud feedback
To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnosticsfixed google cloud sample code for golang
Use signed URLs  |  Cloud CDN  |  Google Cloud
// readKeyFile reads the base64url-encoded key file and decodes it.
func readKeyFile(path string) ([]byte, error) {
        b, err := ioutil.ReadFile(path)
        if err != nil {
                return nil, fmt.Errorf("failed to read key file: %+v", err)
        }
-       d := make([]byte, base64.URLEncoding.DecodedLen(len(b)))
-       n, err := base64.URLEncoding.Decode(d, b)
+       d := make([]byte, base64.RawURLEncoding.DecodedLen(len(b)))
+       n, err := base64.RawURLEncoding.Decode(d, b)
        if err != nil {
                return nil, fmt.Errorf("failed to base64url decode: %+v", err)
        }
        return d[:n], nil
}
Therefore, for Cloud CDN key values, base64 url safe and padding with = is desirable, but currently random_id does not provide such output. One of the outputs of random_id, b64_std, is not url safe, but it is base64 encoded with = padding. So I modified the code to take advantage of this and use the replace function to convert it to url safe.
key_value       = replace(replace(random_id.url_signature.b64_std,"+", "-") ,"/", "_")I have confirmed by looking at the implementation in the random_id repository (hashicorp/terraform-provider-random ) that b64_url and b64_std implemented in Go as follows
b64Std := base64.StdEncoding.EncodeToString(bytes)
id := base64.RawURLEncoding.EncodeToString(bytes)
...
B64URL:     types.StringValue(prefix + id),I think that base64.URLEncoding.EncodeToString(bytes) is suitable in this case, not base64.RawURLEncoding.EncodeToString(bytes).
So I think that we need to add the output to random_id. (ActuallyI have issued a PR regarding this.)
What kind of contribution is this issue about?
- configuration sample
 
better sample for the Google Cloud Platform
resource "google_compute_backend_bucket_signed_url_key" "backend_key_b64_std_url_safe" {
  name           = "test-key-b64-std-url-safe-key"
  key_value      = replace(replace(random_id.url_signature.b64_std, "+", "-"), "/", "_")
  backend_bucket = google_compute_backend_bucket.test_backend.name
}
Related PR(s), if any:
- Add padded url safe base64 encoding b64_url_pad for random_id outputs terraform-provider-random#352
 - fix key value for cloud cdn to issue signed urls GoogleCloudPlatform/magic-modules#7166
 
old issue: #7202
Details
> terraform -version
Terraform v1.3.7
on darwin_arm64
+ provider registry.terraform.io/hashicorp/google v4.50.0
+ provider registry.terraform.io/hashicorp/random v3.4.3
terraform apply
https://gist.github.com/BIwashi/8a1c8a5f3c1be7f98566df24a9a32c47
gcloud command
success (b64_std + url safe)
> gcloud compute sign-url \
  "https://storage.cloud.google.com/test-storage-bucket-8c0dadbc-cea3-4819-9ded-3cf3990130ba/test.jpeg" \
  --key-name "test-key-b64-std-url-safe-key" \
  --key-file key-file-b64-std-url-safe \
  --expires-in 5m \
  --validate
signedUrl: https://storage.cloud.google.com/test-storage-bucket-8c0dadbc-cea3-4819-9ded-3cf3990130ba/test.jpeg?Expires=1674833243&KeyName=test-key-b64-std-url-safe-key&Signature=FBVJRNWPzyaQ9BzVlf8hkkwCqI0=
validationResponseCode: 200fail (b64 url)
> gcloud compute sign-url \
  "https://storage.cloud.google.com/test-storage-bucket-8c0dadbc-cea3-4819-9ded-3cf3990130ba/test.jpeg" \
  --key-name "test-key-b64-url" \
  --key-file key-file-b64-url \
  --expires-in 5m \
  --validate
ERROR: gcloud crashed (Error): Incorrect padding
If you would like to report this issue, please run the following command:
  gcloud feedback
To check gcloud for common problems, please run the following command:
  gcloud info --run-diagnosticssuccess (b64_std) <-- I dont'n know why.... The Google Cloud Platform official documentation instructs to use base64 url.
> gcloud compute sign-url \
  "https://storage.cloud.google.com/test-storage-bucket-8c0dadbc-cea3-4819-9ded-3cf3990130ba/test.jpeg" \
  --key-name "test-key-b64-std" \
  --key-file key-file-b64-std \
  --expires-in 5m \
  --validate
signedUrl: https://storage.cloud.google.com/test-storage-bucket-8c0dadbc-cea3-4819-9ded-3cf3990130ba/test.jpeg?Expires=1674833437&KeyName=test-key-b64-std&Signature=rSU1Lln0Bi58Q8prkET-nSv_5Sc=
validationResponseCode: 200b/318665331