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

Implement an authorization layer for operator-to-workspace communication #609

Closed
EronWright opened this issue Jul 24, 2024 · 2 comments
Closed
Assignees
Labels
kind/task Work that's part of an ongoing epic resolution/fixed This issue was fixed
Milestone

Comments

@EronWright
Copy link
Contributor

EronWright commented Jul 24, 2024

It is important to protect the RPC endpoint from unauthorized use. For authentication, one option is to use the operator's service account token (a projected volume) as a bearer token. For authorization, one could use the Kubernetes API server (SubjectAccessReview). This together would be an effective alternative to using a shared secret and developing a custom authorization layer.

To implement the above, either:

  1. place the kube-rbac-proxy in front of the RPC server (as a sidecar container) in gRPC mode
  2. implement kubernetes authn/authz directly in the RPC server as an interceptor

The latter option is a more coupled solution but is less complex at runtime. Option (1) also has the complication of needing another image and worrying about whether it is compatible with the restricted security profile. Update: we used (2).

@pulumi-bot pulumi-bot added the needs-triage Needs attention from the triage team label Jul 24, 2024
@EronWright EronWright changed the title Implement an authorization layer for operator-to-workspace communication. Implement an authorization layer for operator-to-workspace communication Jul 24, 2024
@cleverguy25
Copy link

Added to epic #586

@EronWright EronWright removed the needs-triage Needs attention from the triage team label Jul 24, 2024
@EronWright
Copy link
Contributor Author

EronWright commented Jul 30, 2024

A reference for developing grpc security plugins: https://github.com/grpc-ecosystem/go-grpc-middleware?tab=readme-ov-file

@mjeffryes mjeffryes added the kind/task Work that's part of an ongoing epic label Aug 23, 2024
@EronWright EronWright removed their assignment Sep 6, 2024
@mjeffryes mjeffryes assigned rquitales and EronWright and unassigned rquitales Sep 9, 2024
@mjeffryes mjeffryes added this to the 0.110 milestone Sep 12, 2024
@EronWright EronWright removed their assignment Sep 16, 2024
@blampe blampe modified the milestones: 0.110, 0.111 Oct 1, 2024
@blampe blampe assigned EronWright and unassigned blampe Oct 1, 2024
EronWright added a commit that referenced this issue Oct 12, 2024
…ion (#712)

<!--Thanks for your contribution. See [CONTRIBUTING](CONTRIBUTING.md)
    for Pulumi's contribution guidelines.

    Help us merge your changes more quickly by adding more details such
    as labels, milestones, and reviewers.-->

### Overview

This PR implements an authentication and authorization layer for the
agent's RPC endpoint.

Authentication is performed by authenticating a bearer token via the
TokenReview API. The operator uses its built-in service account token.
Authorization is performed via the SubjectAccessReview API, which checks
for following RBAC permission:
```yaml
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
rules:
- apiGroups:
  - auto.pulumi.com
  resources:
  - workspaces/rpc
  verbs:
  - use
```

The workspace pod's service account must be granted the
`system:auth-delegator` role using a `ClusterRoleBinding`. For.
convenience, the installer creates a service account named `pulumi` into
the `default` namespace, with an associated binding.

The operator itself is granted the necessary permission to access the
RPC endpoint.

### Proposed changes

<!--Give us a brief description of what you've done and what it solves.
-->

- [x] agent grpc interceptor
- [x] agent command args (`--auth-mode=kube`,
`--kube-workspace-name=random-yaml`)
- [x] operator client credentials
- [x] operator RBAC permissions
- [ ] ~cluster role binding for workspace service account (to
ClusterRole named `system:auth-delegator`)~
- [x] install a "default/pulumi" service account with RBAC
- [x] Provide a Flux sample network policy
- [x] Update the e2e test manifests to have requisite account, rbac, and
network policy.

### Future Enhancement

This implementation uses the operator's default service account token,
but to further improve security it should use
an audience-scoped token, where the audience is the agent service
address as opposed to the API server. Such tokens may be created by the
operator with a call to TokenRequest, and checked with TokenReview by
adding the expected audience to the context
(`authenticator.WithAudience`).

### Related issues (optional)

<!--Refer to related PRs or issues: #1234, or 'Fixes #1234' or 'Closes
#1234'.
Or link to full URLs to issues or pull requests in other GitHub
repositories. -->

Closes #609 

#### Examples
Some example requests:
```
random-yaml-workspace-0 pulumi 2024-10-09T21:09:43.905Z INFO    cmd.serve.grpc  finished unary call with code OK        {"grpc.start_time": "2024-10-09T21:09:43Z", "grpc.request.deadline": "2024-10-09T21:59:43Z", "system": "grpc", "span.kind": "server", "grpc.service": "agent.AutomationService", "grpc.method": "WhoAmI", "user.id": "81be050c-9ad4-4708-9a52-413064700747", "user.name": "system:serviceaccount:default:dev", "peer.address": "127.0.0.1:56394", "auth.mode": "kubernetes", "grpc.code": "OK", "grpc.time_ms": 441.086}

random-yaml-workspace-0 pulumi 2024-10-09T21:09:52.934Z INFO    cmd.serve.grpc  finished unary call with code Unauthenticated   {"grpc.start_time": "2024-10-09T21:09:52Z", "grpc.request.deadline": "2024-10-09T21:59:52Z", "system": "grpc", "span.kind": "server", "grpc.service": "agent.AutomationService", "grpc.method": "WhoAmI", "peer.address": "127.0.0.1:57380", "auth.mode": "kubernetes", "error": "rpc error: code = Unauthenticated desc = Request unauthenticated with Bearer", "grpc.code": "Unauthenticated", "grpc.time_ms": 0.095}
```
@EronWright EronWright added the resolution/fixed This issue was fixed label Oct 12, 2024
@github-project-automation github-project-automation bot moved this from In Progress to Done in Pulumi Kubernetes Operator v2 Oct 12, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/task Work that's part of an ongoing epic resolution/fixed This issue was fixed
Projects
No open projects
Status: Done
Development

No branches or pull requests

6 participants