Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

removed org specific information #5

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 49 additions & 0 deletions go/gcp-escalation/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#syntax=docker/dockerfile:1
# Container image that runs your code
FROM golang:1.18.3-stretch AS builder

# Install upx (upx.github.io) to compress the compiled action
RUN apt-get update && apt-get -y install upx

# Turn on Go modules support and disable CGO
ENV GO111MODULE=on CGO_ENABLED=0


RUN mkdir src/gcp-akeyless-producer
WORKDIR /src/gcp-akeyless-producer
COPY . .

# Compile the action - the added flags instruct Go to produce a
# standalone binary
RUN go build \
-a \
-trimpath \
-ldflags "-s -w" \
-tags netgo \
-o /bin/gcp-akeyless-producer \
.

# Strip any symbols - this is not a library
RUN strip /bin/gcp-akeyless-producer

# Compress the compiled action
RUN upx -q -9 /bin/gcp-akeyless-producer

# Step 2

# Use the most basic and empty container - this container has no
# runtime, files, shell, libraries, etc.
FROM scratch

# Copy over SSL certificates from the first step - this is required
# if our code makes any outbound SSL connections because it contains
# the root CA bundle.
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/

# Copy over the compiled action from the first step
COPY --from=builder /bin/gcp-akeyless-producer /bin/gcp-akeyless-producer

EXPOSE 8080
# Specify the container's entrypoint as the action

ENTRYPOINT ["/bin/gcp-akeyless-producer"]
54 changes: 54 additions & 0 deletions go/gcp-escalation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Akeyless Custom Producer To Escalate GCP Permissions

GCP Escalation Producer will temporarily escalate users to the permissions given in the payload.

1. [Purpose](#purpose)
2. [Deployment](#deployment)
3. [Permissions](#permissions)
4. [Usage](#usage)
5. [Security](#security)

## Purpose

We need a way to control cloud permissions from okta, with just in time privileges. Akeyless has the ability to generate dynamic credentials, and also the ability to write "custom" dynamic credentials based on writing your own producer here: https://docs.akeyless.io/docs/custom-producer. The idea is to have groups pushed from okta, in the form of saml subclaims, which are used in their role based access control to give access to custom dynamic secrets, that will reach out to google IAM, temporarily escalate privileges to whats specified in the akeyless "payload", and then after the akeyless TTL is reached, deescalate them back to base privileges.

## Deployment

The GCP Escalation producer is a docker container that runs in Google's serverless container platform: Cloud Run. You will need set the container to accept unauthenticated requests (it will be authenticated through akeyless itself), and set the environment variable "AKEYLESS_ACCESS_ID" to the gateway access ID of the akeyless auth method for the gateway that will be connecting to and using the producer.


## Permissions

The GCP Producer requires the following permissions in google cloud:
1. Security Admin on your organization - Needed to Manage Privilege Escalations
2. Cloud Run Admin - Cloud Run Admin is needed if you want to use github actions to overwrite an existing deployment with a new release
3. Service Account User on project compute developer default account such as [email protected]
4. Service Account User for the GCP producer's own service account for itself
5. Artifact Registry Writer for the artifact registry you wish to deploy the container to, if you use google artifact registry

## Usage
You can create a dynamic secret in the GUI by going to "Secrets and Keys" in the left hand menu, choose dynamic secret, and then choose "Custom" under the "Infra" section. You will need to give it a name, a location (path), description and tags. The Create and Revoke URLs are the cloud run URL, with /sync/create and /sync/revoke appended. No rotation is required since we won't be managing secrets. You can leave the webhook timeout as default, set the user TTL to the time to keep the escalation active before revoking, and specify the gateway that will be communicating with the producer.

The Payload will be in the following format (JSON).

{"role": <GCP_RESOURCE_ID>, "resource_type": <RESOURCE_TYPE>, "resource_id", <RESOURCE_ID>}

GCP resource ID is the full ID of the role in google cloud. If the role id is a custom one, you'll have to include the full path included in the ID.
RESOURCE_TYPE can be project, folder, or organization
RESOURCE_ID will be the ID of the project, folder, or organization:

Example:

{"role": "projects/example-project-name/roles/owner","resource_type": "project", "resource_id": "example-project-name"}

If you have problems you can check the logs in cloud run, but the common issues are your akeyless gateway ID isn't set in the cloud run environment variables (must use the actual gateway auth id, not the access id you're logged in with), or that the role you're assigning doesn't exist in the scope (project/org etc..) that you're trying to assign. The logs should display these errors.

If all goes well the secret will perform an unauthenticated "dry run" where it sends a temporary ID that is returned back, which lets the secret be created. Afterwards, you can use the dynamic secret to escalate permissions. If you receive an error saying that the gateway doesn't have permissions, you need to verify that the akeyless access ID you're using is configured as an allowed access ID in the gateway (gateways section in akeyless gui).

## Security

The producer will verify that the authentication credentials that akeyless sends, match the access ID in the cloud run environment variable, and was signed by that access ID. On top of this, to stop any user logged in from creating their on dynamic secrets, there is a regular expression that will block any requests that don't come from an "item_name" in the client information sent to the producer, that checks to make sure the dynamic secret came from the right path: /dynamic-secrets/cloud-user-access/gcp (gcp isn't necessarily a folder, but is intended as a prefix for name such as gcp-project-producer, etc...
Example:

/dynamic-secrets/cloud-user-access/gcp-dynamic-secret will work

36 changes: 36 additions & 0 deletions go/gcp-escalation/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module gcp-privileges

go 1.18

require (
github.com/GoogleCloudPlatform/functions-framework-go v1.5.3
github.com/akeylesslabs/custom-producer/go v0.0.0-20220120141447-92f7ff159646
github.com/celo-org/gcp-akeyless-producer v0.0.0-20220807170334-28a261789e03
google.golang.org/api v0.91.0
)

require (
cloud.google.com/go/compute v1.7.0 // indirect
github.com/cloudevents/sdk-go/v2 v2.6.1 // indirect
github.com/golang-jwt/jwt/v4 v4.4.2 // indirect
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/uuid v1.3.0 // indirect
github.com/googleapis/enterprise-certificate-proxy v0.1.0 // indirect
github.com/googleapis/gax-go/v2 v2.4.0 // indirect
github.com/json-iterator/go v1.1.10 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.1 // indirect
go.opencensus.io v0.23.0 // indirect
go.uber.org/atomic v1.4.0 // indirect
go.uber.org/multierr v1.1.0 // indirect
go.uber.org/zap v1.10.0 // indirect
golang.org/x/net v0.0.0-20220624214902-1bab6f366d9e // indirect
golang.org/x/oauth2 v0.0.0-20220622183110-fd043fe589d2 // indirect
golang.org/x/sys v0.0.0-20220624220833-87e55d714810 // indirect
golang.org/x/text v0.3.7 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20220624142145-8cd45d7dbd1f // indirect
google.golang.org/grpc v1.47.0 // indirect
google.golang.org/protobuf v1.28.0 // indirect
)
Loading