Implement SPIFFE Broker Endpoint & API#6594
Conversation
Signed-off-by: arndt-s <17650715+arndt-s@users.noreply.github.com>
arndt-s
left a comment
There was a problem hiding this comment.
Self review highlighting parts that I would like to get feedback/opinions on please.
| # admin_socket_path = "" | ||
|
|
||
| # authorized_delegates: SPIFFE ID list of the authorized delegates | ||
| # authorized_delegates = [ |
There was a problem hiding this comment.
I'm unsure whether we should allow for a dedicated allow list for the broker endpoint or reuse the same?
| return c.AdminSocketPath != "" | ||
| } | ||
|
|
||
| func (c *agentConfig) getBrokerAddr() (net.Addr, error) { |
There was a problem hiding this comment.
For now I'm only supporting UDS, once the Broker API evolves we may allow serving it on TCP too.
| ) | ||
|
|
||
| // Allow AttestationResult to be used as go-spiffe SVID and bundle sources. | ||
| // TODO(arndt): Check whether the key of the agent is ok to be exposed to other parties. |
There was a problem hiding this comment.
I think this is worth a discussion.
| TrustDomain: a.c.TrustDomain, | ||
| AuthorizedDelegates: a.c.AuthorizedDelegates, | ||
| SVIDSource: as, | ||
| BundleSource: manager.GetX509Bundle(), |
There was a problem hiding this comment.
I wasn't sure what's better here, us the attestation result as a bundle source or the one from the manager?
| if err != nil { | ||
| return err | ||
| } | ||
| _ = rpccontext.Logger(ctx).WithField("broker_peer", peer.String()) |
There was a problem hiding this comment.
There's no log here .. I'm considering to add Debug logs for each RPC?
| } | ||
|
|
||
| func New(c *Config) (*Endpoints, error) { | ||
| switch { |
There was a problem hiding this comment.
Is this pattern ok? Delegated Identity doesn't have it and would panic if misconfigured?
|
|
||
| // TODO(arndt): Delegated Identity API allows to be served without any authorized peer. | ||
| // I think it's better to fail as it's a misconfiguration and having that socket up | ||
| // without any authorized peer is just a potential security risk. |
There was a problem hiding this comment.
this is also worth a discussion
| ) | ||
|
|
||
| e.registerBrokerAPI(server) | ||
| reflection.Register(server) |
There was a problem hiding this comment.
Any objections in having it here? I don't see a drawback and could help brokers that don't want to know the proto?
| // I suppose technically it's not possible on the admin API to encounter this, but considering that | ||
| // the SPIFFE Broker Endpoint may be offered over the network in the future I think it's better to | ||
| // enforce this here. | ||
| if id.TrustDomain() != trustDomain { |
There was a problem hiding this comment.
I added a configuration sanity check here. Any objections?
| // TODO(arndt): Delegated Identity API allows to be served without any authorized peer. | ||
| // I think it's better to fail as it's a misconfiguration and having that socket up | ||
| // without any authorized peer is just a potential security risk. | ||
| if len(e.c.AuthorizedDelegates) == 0 { |
There was a problem hiding this comment.
@arndt-s
This means the authorized delegates SpiffeIDs must be well known and configured ahead the deployment happens.
The problem is that when deploying SPIRE on K8s/OCP you not necessary know what they are.
Let's take Istio as an example.
First user deployed SPIRE, next deploys Istio.
The SPIFFE IDs are created dynamically based on the ClusterSPIFFEID CRs
With if len(e.c.AuthorizedDelegates) == 0 the Spire agent won't become healthy until relevant Spiffe ID is created and the Spire-Agent config map being updated.
I think we should disable this constraint, or at least make it optional.
There was a problem hiding this comment.
Generally you should be able to determine what SPIFFE IDs your workload is going to receive ahead of time. For example in k8s most of the time this is defined from namespace and service account names, which I imagine you have some control over.
It's possible to include more randomised information in there, e.g. pod uid in k8s, but I don't think that's particularly common. If that's the case, the policy specified here through this authorised delegates list could get some support for wildcarding.
Before doing that we'd like to see that there is an actually need for it, so if you have a use case where that's necessary let us know. Either way, that's not something that needs to be handled by this PR.
| if err != nil { | ||
| return nil, fmt.Errorf("workload attestor %q failed: %w", a.Name(), err) | ||
| } | ||
| // // The agent health check currently exercises the Workload API. Since this |
There was a problem hiding this comment.
Can broker use agent PID? I'd like to block that? What if it uses the pod UID of the agent?
TODO for myself to find a solution so that workload.go get's to know it's itself without knowing the details of the reference.
There was a problem hiding this comment.
How do others make images with custom api & plugin packages?
|
Things to discuss:
|
This is a Work In Progress.
Reference implementation for spiffe/spiffe#340
api-sdk PR: spiffe/spire-api-sdk#92
plugin-sdk PR: spiffe/spire-plugin-sdk#71
Pull Request check list
Affected functionality
Description of change
Which issue this PR fixes