{"id":15221491,"url":"https://github.com/googlecloudplatform/berglas","last_synced_at":"2025-05-14T05:09:27.079Z","repository":{"id":34602150,"uuid":"180709218","full_name":"GoogleCloudPlatform/berglas","owner":"GoogleCloudPlatform","description":"A tool for managing secrets on Google Cloud","archived":false,"fork":false,"pushed_at":"2025-04-16T21:01:52.000Z","size":7070,"stargazers_count":1260,"open_issues_count":1,"forks_count":97,"subscribers_count":31,"default_branch":"main","last_synced_at":"2025-05-09T15:43:54.548Z","etag":null,"topics":["google-cloud","google-cloud-kms","google-cloud-storage","gsecrets","secret-management","secrets-management"],"latest_commit_sha":null,"homepage":"https://cloud.google.com/secret-manager","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/GoogleCloudPlatform.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2019-04-11T03:42:50.000Z","updated_at":"2025-04-28T21:52:15.000Z","dependencies_parsed_at":"2023-12-20T11:44:01.424Z","dependency_job_id":"5233d96c-df9d-4eff-bf59-e70f3bae96f4","html_url":"https://github.com/GoogleCloudPlatform/berglas","commit_stats":{"total_commits":345,"total_committers":29,"mean_commits":11.89655172413793,"dds":"0.24927536231884062","last_synced_commit":"24658b75f664c476be9468846fced6279dcce014"},"previous_names":[],"tags_count":28,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fberglas","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fberglas/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fberglas/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/GoogleCloudPlatform%2Fberglas/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/GoogleCloudPlatform","download_url":"https://codeload.github.com/GoogleCloudPlatform/berglas/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254076850,"owners_count":22010611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["google-cloud","google-cloud-kms","google-cloud-storage","gsecrets","secret-management","secrets-management"],"created_at":"2024-09-28T15:05:16.723Z","updated_at":"2025-05-14T05:09:27.066Z","avatar_url":"https://github.com/GoogleCloudPlatform.png","language":"Go","readme":"# Berglas\n\n[![Build Status](https://img.shields.io/github/actions/workflow/status/GoogleCloudPlatform/berglas/test.yml?branch=main\u0026style=flat-square)](https://github.com/GoogleCloudPlatform/berglas/actions/workflows/test.yml?query=branch%3Amain)\n[![GoDoc](https://img.shields.io/badge/go-documentation-blue.svg?style=flat-square)][berglas-godoc]\n\n![Berglas Logo](/logos/berglas.svg)\n\nBerglas is a command line tool and library for storing and retrieving\nsecrets on Google Cloud. Secrets are encrypted with [Cloud KMS][cloud-kms] and\nstored in [Cloud Storage][cloud-storage]. An interoperable layer also exists with [Secret Manager][secret-manager].\n\n- As a **CLI**, `berglas` automates the process of encrypting, decrypting, and\n  storing data on Google Cloud.\n\n- As a **library**, `berglas` automates the inclusion of secrets into various\n  Google Cloud runtimes.\n\n**Berglas is not an officially supported Google product.**\n\n\n## Setup\n\n### Prerequisites\n\n1. Install the [Cloud SDK][cloud-sdk] for your operating system. Alternatively,\n   you can run these commands from [Cloud Shell][cloud-shell], which has the SDK\n   and other popular tools pre-installed.\n\n    If you are running from your local machine, you also need Default\n    Application Credentials:\n\n    ```text\n    gcloud auth application-default login\n    ```\n\n    This will open a web browser and prompt for a login to your Google account.\n    On headless devices, you will need to create a service account. For more\n    information, please see the [authentication](#authentication) section.\n\n1. Install the `berglas` CLI using **one** of the following methods:\n\n    - Install a pre-compiled binary for your operating system from the [latest\n      releases](releases).\n\n    - Use an [official Docker container](https://us-docker.pkg.dev/berglas/berglas/berglas):\n\n      ```text\n      docker run -it us-docker.pkg.dev/berglas/berglas/berglas\n      ```\n\n      Note: older Docker container images are available on Container Registry\n      and Artifact Registry, but new versions are not published there.\n\n    - Use [Homebrew](https://brew.sh/) on macOS:\n\n      ```sh\n      brew install berglas\n      ```\n\n      Note: sometimes the Homebrew formula can be several versions behind.\n\n    - Install from source (requires a working Go installation):\n\n      ```sh\n      go install github.com/GoogleCloudPlatform/berglas/v2@latest\n      ```\n\n1. Export your project ID as an environment variable. The rest of this setup\n   guide assumes this environment variable is set:\n\n    ```text\n    export PROJECT_ID=my-gcp-project-id\n    ```\n\n    Please note, this is the project _ID_, not the project _name_ or project\n    _number_. You can find the project ID by running `gcloud projects list` or\n    in the web UI.\n\n### Secret Manager Storage\n\n1. Enable required services on the project:\n\n    ```text\n    gcloud services enable --project ${PROJECT_ID} \\\n      secretmanager.googleapis.com\n    ```\n\n### Cloud Storage Storage\n\n1. Export your desired Cloud Storage bucket name. The rest of this setup guide\n   assumes this environment variable is set:\n\n    ```text\n    export BUCKET_ID=my-secrets\n    ```\n\n    Replace `my-secrets` with the name of your bucket. Set only the name,\n    without the `gs://` prefix. **This bucket should not exist yet!**\n\n1. Enable required services on the project:\n\n    ```text\n    gcloud services enable --project ${PROJECT_ID} \\\n      cloudkms.googleapis.com \\\n      storage-api.googleapis.com \\\n      storage-component.googleapis.com\n    ```\n\n1. Bootstrap a Berglas environment. This will create a new Cloud Storage bucket\n   for storing secrets and a Cloud KMS key for encrypting data.\n\n    ```text\n    berglas bootstrap --project $PROJECT_ID --bucket $BUCKET_ID\n    ```\n\n    This command uses the default values. You can customize the storage bucket\n    and KMS key configuration using the optional flags. Run `berglas bootstrap\n    -h` for more details.\n\n    If you want full control over the creation of the Cloud Storage and Cloud\n    KMS keys, please see the [custom setup documentation][custom-setup].\n\n1. _(Optional)_ Bootstrap a Berglas environment specifying a bucket location. By\n   default the berglas bucket is created in the multi-regional location `US`.\n   You can specify your location by using the following command. Please see the\n   list of supported locations in the [GCP bucket location documentation\n   page](https://cloud.google.com/storage/docs/locations)\n\n    ```text\n    export BUCKET_LOCATION=europe-west1\n    berglas bootstrap \\\n      --project $PROJECT_ID \\\n      --bucket $BUCKET_ID \\\n      --bucket-location $BUCKET_LOCATION\n    ```\n\n    This command uses the default values. You can customize the storage bucket\n    and KMS key configuration using the optional flags. Run `berglas bootstrap\n    -h` for more details.\n\n    If you want full control over the creation of the Cloud Storage and Cloud\n    KMS keys, please see the [custom setup documentation][custom-setup].\n\n1. _(Optional)_ Enable [Cloud Audit logging][cloud-audit] on the bucket:\n\n    Please note this will enable audit logging on all Cloud KMS keys and all\n    Cloud Storage buckets in the project, which may incur additional costs.\n\n    1. Download the exiting project IAM policy:\n\n        ```text\n        gcloud projects get-iam-policy ${PROJECT_ID} \u003e policy.yaml\n        ```\n\n    1. Add Cloud Audit logging for Cloud KMS and Cloud Storage:\n\n        ```text\n        cat \u003c\u003cEOF \u003e\u003e policy.yaml\n        auditConfigs:\n        - auditLogConfigs:\n          - logType: DATA_READ\n          - logType: ADMIN_READ\n          - logType: DATA_WRITE\n          service: cloudkms.googleapis.com\n        - auditLogConfigs:\n          - logType: ADMIN_READ\n          - logType: DATA_READ\n          - logType: DATA_WRITE\n          service: storage.googleapis.com\n        EOF\n        ```\n\n    1. Submit the new policy:\n\n        ```text\n        gcloud projects set-iam-policy ${PROJECT_ID} policy.yaml\n        ```\n\n    1. Remove the updated policy from local disk:\n\n        ```text\n        rm policy.yaml\n        ```\n\n\n## CLI Usage\n\n1. Create a secret:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas create sm://${PROJECT_ID}/foo my-secret-data\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas create ${BUCKET_ID}/foo my-secret-data \\\n      --key projects/${PROJECT_ID}/locations/global/keyRings/berglas/cryptoKeys/berglas-key\n    ```\n\n1. Grant access to a secret:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas grant sm://${PROJECT_ID}/foo --member user:user@mydomain.com\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas grant ${BUCKET_ID}/foo --member user:user@mydomain.com\n    ```\n\n1. Access a secret's data:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas access sm://${PROJECT_ID}/foo\n    my-secret-data\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas access ${BUCKET_ID}/foo\n    my-secret-data\n    ```\n\n1. Spawn a child process with secrets populated in the child's environment:\n\n    ```text\n    berglas exec -- myapp --flag-a --flag-b\n    ```\n\n    This will spawn `myapp` with an environment parsed by berglas.\n\n1. Access data from a specific version/generation of a secret:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas access sm://${PROJECT_ID}/foo#1\n    my-previous-secret-data\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas access ${BUCKET_ID}/foo#1563925940580201\n    my-previous-secret-data\n    ```\n\n1. Revoke access to a secret:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas revoke sm://${PROJECT_ID}/foo --member user:user@mydomain.com\n    my-previous-secret-data\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas revoke ${BUCKET_ID}/foo --member user:user@mydomain.com\n    ```\n\n1. Delete a secret:\n\n    Using Secret Manager storage:\n\n    ```text\n    berglas delete sm://${PROJECT_ID}/foo\n    ```\n\n    Using Cloud Storage storage:\n\n    ```text\n    berglas delete ${BUCKET_ID}/foo\n    ```\n\nIn addition to standard Unix exit codes, if the CLI exits with a known error,\nBerglas will exit with one of the following:\n\n- `60` - API error. Berglas got a bad response when communicating with an\n  upstream API.\n\n- `61` - Misuse error. You gave unexpected input or behavior. Please read the\n  error message. Open an issue if you think this is a mistake.\n\nThe only exception is `berglas exec`, which will exit with the exit status of\nits child command, if one was provided.\n\n\n## Integrations\n\n- **App Engine (Flex)** - When invoked via [App Engine Flex][app-engine-flex],\n  Berglas resolves environment variables to their plaintext values using the\n  [`berglas://reference syntax][reference-syntax]. This integration works with\n  any language runtime because berglas serves as the entrypoint to the Docker\n  container.\n\n- **App Engine (Standard)** - When invoked via [App Engine][app-engine],\n  Berglas resolves environment variables to their plaintext values using the\n  [`berglas://`reference syntax][reference-syntax]. This integration only works\n  with the Go language runtime because it requires importing the `auto/`\n  package.\n\n- **Cloud Run** - When invoked via [Cloud Run][cloud-run], Berglas resolves\n  environment variables to their plaintext values using the [`berglas://`\n  reference syntax][reference-syntax]. This integration works with any language\n  runtime because berglas serves as the entrypoint to the Docker container.\n\n- **Cloud Functions** - When invoked via [Cloud Functions][cloud-functions],\n  Berglas resolves environment variables to their plaintext values using the\n  [`berglas://` reference syntax][reference-syntax]. This integration only works\n  with the Go language runtime because it requires importing the `auto/`\n  package.\n\n- **Cloud Build** - When invoked via [Cloud Build][cloud-build], Berglas\n  resolves environment variables to plaintext values using the [`berglas://`\n  reference syntax][reference-syntax]. This integration only works with volume\n  mounts, so all Berglas secrets need to specify the `?destination` parameter.\n\n- **Kubernetes** - Kubernetes pods can consume Berglas secrets by installing a\n  [MutatingWebhook][k8s-mutating]. This webhook mutates incoming pods with the\n  [`berglas://` reference syntax][reference-syntax] in environment references to\n  resolve at runtime. This integration works with any container, but all pods\n  requesting berglas secrets must set an command in their Kubernetes manifests.\n\n- **Anything** - Wrap any process with `berglas exec --` and Berglas will\n  parse any local environment variables with the [`berglas://` reference\n  syntax][reference-syntax] and spawn your app as a subprocess with the\n  plaintext environment replaced.\n\n## Logging\n\nBoth the berglas CLI and berglas library support debug-style logging. This logging is off by default because it adds additional overhead and logs information that may be security-sensitive.\n\nThe default logging behavior for the berglas CLI is \"text\" (it can be changed\nwith the `--log-format` flag). The default logging behavior for the berglas\nlibrary is structured JSON which integrates well with Cloud Logging (it can be\nchanged to any valid formatter and you can even inject your own logger).\n\n\n## Library Usage\n\nBerglas is also a Go library that can be imported in Go projects:\n\n```go\nimport (\n\t_ \"github.com/GoogleCloudPlatform/berglas/v2/pkg/auto\"\n)\n```\n\nWhen imported, the `berglas` package will:\n\n1. Download and decrypt any secrets that match the [Berglas environment\nvariable reference syntax][reference-syntax] in the environment.\n\n1. Replace the value for the environment variable with the decrypted secret.\n\nYou can also opt out of auto-parsing and call the library yourself instead:\n\n```go\nimport (\n\t\"context\"\n\t\"log\"\n\t\"os\"\n\n\t\"github.com/GoogleCloudPlatform/berglas/v2/pkg/berglas\"\n)\n\nfunc main() {\n\tctx := context.Background()\n\n\t// This higher-level API parses the secret reference at the specified\n\t// environment variable, downloads and decrypts the secret, and replaces the\n\t// contents of the given environment variable with the secret result.\n\tif err := berglas.Replace(ctx, \"MY_SECRET\"); err != nil {\n\t\tlog.Fatal(err)\n\t}\n\n\t// This lower-level API parses the secret reference, downloads and decrypts\n\t// the secret, and returns the result. This is useful if you need to mutate\n\t// the result.\n\tif v := os.Getenv(\"MY_SECRET\"); v != \"\" {\n\t\tplaintext, err := berglas.Resolve(ctx, v)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tos.Unsetenv(\"MY_SECRET\")\n\t\tos.Setenv(\"MY_OTHER_SECRET\", string(plaintext))\n\t}\n}\n```\n\nFor more examples and documentation, please see the [godoc][berglas-godoc].\n\n\n## Authentication\n\nBy default, Berglas uses Google Cloud Default Application Credentials. If you\nhave [gcloud][cloud-sdk] installed locally, ensure you have application default\ncredentials:\n\n```text\ngcloud auth application-default login\n```\n\nOn GCP services (like Cloud Build, Compute, etc), it will use the service\naccount attached to the resource.\n\nTo use a specific service account, set the `GOOGLE_APPLICATION_CREDENTIALS`\nenvironment variable to the _filepath_ to the JSON file where your credentials\nreside on disk:\n\n```text\nexport GOOGLE_APPLICATION_CREDENTIALS=/path/to/my/credentials.json\n```\n\nTo learn more, please see the [Google Cloud Service Account\ndocumentation][iam-service-accounts].\n\n\n## Authorization\n\nTo control who or what has access to a secret, use `berglas grant` and `berglas\nrevoke` commands. These methods use [Cloud IAM][cloud-iam] internally. Any\nservice account or entity using Berglas will need to authorize using the\n`cloud-platform` scope.\n\n### Secret Manager Storage\n\nCreating a secret requires `roles/secretmanager.admin` on Secret Manager in the\nproject.\n\nAccessing a secret requires `roles/secretmanager.secretAccessor` on the secret\nin Secret Manager.\n\nDeleting a secret requires `roles/secretmanager.admin` on Secret Manager in the\nproject.\n\n### Cloud Storage Storage\n\nCreating a secret requires `roles/storage.objectCreator` on the Cloud Storage\nbucket and `roles/cloudkms.cryptoKeyEncrypter` on the Cloud KMS key.\n\nAccessing a secret requires `roles/storage.objectViewer` on the Cloud Storage\nbucket and `roles/cloudkms.cryptoKeyDecrypter` on the Cloud KMS key.\n\nDeleting a secret requires `roles/storage.objectAdmin` on the Cloud Storage bucket.\n\n\n## Implementation\n\n### Secret Manager Storage\n\nThis section describes the Secret Manager implementation. This knowledge is not\nrequired to use Berglas, but it is included for security-conscious/curious users\nwho want to learn about how Berglas works internally to build a threat model.\n\n1. Berglas calls the [Secret Manager][secret-manager] API directly for all\n   operations.\n\n### Cloud Storage Storage\n\nThis section describes the Cloud Storage implementation. This knowledge is not\nrequired to use Berglas, but it is included for security-conscious/curious users\nwho want to learn about how Berglas works internally to build a threat model.\n\nWhen encrypting a secret:\n\n1. Berglas generates an AES-256-GCM data encryption key (DEK) using [Go's crypto\npackage][go-crypto] for each secret. (N.B. each secret has its own, unique DEK).\n\n1. Berglas encrypts the plaintext data using the locally-generated DEK,\nproducing encrypted ciphertext, prepended with the AES-GCM nonce.\n\n1. Berglas encrypts the DEK using the specified Cloud KMS key, also known as a\nkey encryption key (KEK). This process is called [envelope\nencryption][envelope-encryption].\n\n1. Berglas stores the Cloud KMS key name, encrypted DEK, and encrypted ciphertext\nas a single blob in Cloud Storage.\n\nWhen decrypting a secret:\n\n1. Berglas downloads the blob from Cloud Storage and separates the Cloud KMS key name,\nencrypted DEK, and ciphertext out of the blob.\n\n1. Berglas decrypts the DEK using Cloud KMS. This is part of [envelope encryption][envelope-encryption].\n\n1. Berglas decrypts the ciphertext data locally using the decrypted DEK.\n\n\n## Security \u0026amp; Threat Model\n\nSee the [security and threat model][threat-model].\n\n\n## FAQ\n\n**Q: Should I use Berglas or [Secret Manager][secret-manager]?**\n\u003cbr\u003e\nBerglas is compatible with [Secret Manager][secret-manager] and offers\nconvenience wrappers around managing secrets regardless of whether they reside\nin Cloud Storage or Secret Manager. New projects should investigate using Secret\nManager directly as it has less operational overhead and complexity, but Berglas\nwill continue to support Cloud Storage + Cloud KMS secrets.\n\n**Q: Is there a size limit on the data I can encrypt?**\n\u003cbr\u003e\nBerglas is targeted at application secrets like certificates, passwords, and\nAPI keys. While its possible to encrypt larger binary files like PDFs or images,\nBerglas uses a a GCM cipher mode to encrypt data, meaning the data must fit in\nmemory and is [limited to 64GiB][gcm-limits].\n\n**Q: Why do you use [envelope encryption][envelope-encryption] instead of\nencrypting the data directly with [Cloud KMS][cloud-kms]?**\n\u003cbr\u003e\nEnvelope encryption allows for encrypting the data at the _application layer_,\nand it enables encryption of larger payloads, since Cloud KMS has a limit on the\nsize of the payload it can encrypt. By using envelope encryption, Cloud KMS\nalways encrypts a fixed size data (the AES-256-GCM key). This saves bandwidth\n(since large payloads are encrypted locally) and increases the size of the data\nwhich can be encrypted.\n\n**Q: Why does Berglas need permission to view my GCP resource?**\n\u003cbr\u003e\nBerglas communicates with the API to read the environment variables that were\nset on the resource at deploy time. Otherwise, a package could inject arbitrary\nenvironment variables in the Berglas format during application boot.\n\n**Q: I renamed a secret in Cloud Storage and now it fails to decrypt - why?**\n\u003cbr\u003e\nBerglas encrypts secrets with additional authenticated data including the name\nof the secret. This reduces the chance an attacker can escalate privilege by\nconvincing someone to rename a secret so they can gain access.\n\n**Q: Why is it named Berglas?**\n\u003cbr\u003e\nBerglas is a famous magician who is best known for his secrets.\n\n\n## Contributing\n\nPlease see the [contributing\nguidelines](https://github.com/GoogleCloudPlatform/berglas/tree/main/CONTRIBUTING.md).\n\n\n## License\n\nThis library is licensed under Apache 2.0. Full license text is available in\n[LICENSE](https://github.com/GoogleCloudPlatform/berglas/tree/main/LICENSE).\n\n\n\n[app-engine]: https://cloud.google.com/appengine/\n[app-engine-flex]: https://cloud.google.com/appengine/docs/flexible/\n[cloud-audit]: https://cloud.google.com/logging/docs/audit/configure-data-access#config-api\n[cloud-build]: https://cloud.google.com/cloud-build\n[cloud-kms]: https://cloud.google.com/kms\n[cloud-kms-iam]: https://cloud.google.com/kms/docs/iam\n[cloud-functions]: https://cloud.google.com/functions\n[cloud-iam]: https://cloud.google.com/iam\n[cloud-run]: https://cloud.google.com/run\n[cloud-storage]: https://cloud.google.com/storage\n[cloud-storage-iam]: https://cloud.google.com/storage/docs/access-control/iam\n[cloud-shell]: https://cloud.google.com/shell\n[cloud-sdk]: https://cloud.google.com/sdk\n[k8s-mutating]: https://kubernetes.io/docs/reference/access-authn-authz/admission-controllers/\n[secret-manager]: https://cloud.google.com/secret-manager\n[go-crypto]: https://golang.org/pkg/crypto/\n[envelope-encryption]: https://cloud.google.com/kms/docs/envelope-encryption\n[custom-setup]: https://github.com/GoogleCloudPlatform/berglas/blob/main/doc/custom-setup.md\n[reference-syntax]: https://github.com/GoogleCloudPlatform/berglas/blob/main/doc/reference-syntax.md\n[threat-model]: https://github.com/GoogleCloudPlatform/berglas/blob/main/doc/threat-model.md\n[releases]: https://github.com/GoogleCloudPlatform/berglas/releases\n[berglas-godoc]: https://godoc.org/github.com/GoogleCloudPlatform/berglas\n[gcm-limits]: https://crypto.stackexchange.com/questions/31793/plain-text-size-limits-for-aes-gcm-mode-just-64gb\n[iam-service-accounts]: https://cloud.google.com/iam/docs/service-accounts\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fberglas","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgooglecloudplatform%2Fberglas","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgooglecloudplatform%2Fberglas/lists"}