Open implementation of Programmatic Identity Aware Proxy for Google Cloud workload to workload authentication using Google Service Account.
Performs validity and signature verification of Google Service Account JWT - while also verifying subject of claim email has role bidning
roles/iap.httpsResourceAccess inside project. Role roles/iap.httpsResourceAccess (as with Identity Aware Proxy) is required for authentication.
Conditional expressions are supported. A role binding can be restricted to only allow communication to a single specific host and path.
The following token types are supported for Google Service Account:
- ID-Token
- Self-Signed JWTs
Please reference Google Cloud Token Types for more information. For Self-Signed JWTs please ensure to follow specification as required by Google.
- Identity Aware Proxy for Google Cloud is only available in BeyondCorp Enterprise.
- There is other solutions available on GitHub, however, none of are really suitable and made compatible with existing IAM on Google Cloud.
- Signature verification using
JWK. Source ofJWKis determined given type of JWT. iatandexpclaim verification. Leeway forJWTis configurable. Default is 1 minute.audclaim must be equal to request url.- Role
roles/iap.httpsResourceAccessoris verified given subject of claim email. Role binding can be granted directly on project, or indirectly, via membership in Google Workspace group.
❗ Steps {1..3} follow JWT-verification as described by Google Cloud. Step 4 is custom step following
the ideas of Identity Aware Proxy.
❗ After successful {1..4}. Value of claim email is cached. Key is hash, in SHA256, of {JWT || Request URL}.
ttl for cache value is exp - <interval of cleaning routine>. Once token is found in cache - only exp claim validity and step 4 is performed per each request.
❗ The code strives to retain a performance aware profile. Caching is used aggressivly on multiple layers to ensure an overall low 90th percentile response time. To benefit from cache locality, use a ring hash for routing.
5min.
request.path, request.host and request.time are supported with conditional expressions with role roles/iap.httpsResourceAccessor.
If role binding has conditional expression, this conditional expression is compiled and evaluated in memory using cel-go. All conditional
expressions are only compiled once - after first compilation - the program (representing conditional expression) is cached for performance reasons.
❗ Use Dockerfile as example.
Configuration uses pkl-lang. pkl must be available in $PATH. As well, default_config.pkl
and app_config.pkl must be present in same directory as application executable when starting application.
- Groups Reader is required on Google Workspace. Reference Google Workspace Administrator Roles.
- resourcemanager.projects.getIamPolicy is required to list all bindings for role
roles/iap.httpsResourceAccessfor Google Service Account inside project. Usage of custom role is recommended! - Admin API and Cloud Resource Manager API is required on project.
Authentication endpoint. Return code 200 OK given successful authentication, else 401 Unauthorized.
Use the following example (as inspiration), to enable secure, zero trust based communication of workload to workload communication to services on GKE.
Enforce connectivity restrictions to service, traffic must only be permitted through namespace of nginx.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: my-service
spec:
ingress:
- from:
- namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: In
values:
- nginx
ports:
- port: 8080
protocol: TCP
podSelector:
matchLabels:
app: my-service
policyTypes:
- Ingress
Define following configuration on controller of nginx. Ensuring, requests (all ingress registered with controller), only are permitted given valid authentication.
global-auth-snippet: |
proxy_set_header Proxy-Authorization $http_proxy_authorization;
global-auth-url: http://<service name>.<namespace>:8080/auth
X-Original-URL, i.e. from nginx has assumed trust.
AuthorizationorProxy-Authorization.X-Original-URLis configured to be present. This can be changed usingHeaderMappingin configuration.
Kubernetes health endpoint for liveness and readiness. Return code 200 OK.
In scope for open-iap.
- Role
roles/iap.tunnelResourceAccessorforTUNNEL-proxy. - Role bindings on project level are only used. Folders and organization must be implemented as optional feature.
- Consume
IAM Role Audit Events. Ensuring close to real time changes to policy bindings.