# X.509 SVID Watcher example

This example shows how a service can obtain automatically rotated X.509 SVIDs and JWT Bundles from the SPIFFE Workload API.

The first step is to create a Workload API client. The code assumes it is talking to [SPIRE](https://github.com/spiffe/spire) and uses a [workloadapi.ClientOption](https://pkg.go.dev/github.com/spiffe/go-spiffe/v2/workloadapi?tab=doc#ClientOption) to provide the address to the SPIRE Agent socket.

```go
client, err := workloadapi.New(ctx, workloadapi.WithAddr(socketPath))
```

In case `workloadapi.WithAddr` is not provided, the value of `SPIFFE_ENDPOINT_SOCKET` environment variable will be used 

```go
client, err := workloadapi.New(ctx)
```

The library uses a watcher interface  [workloadapi.X509ContextWatcher](https://pkg.go.dev/github.com/spiffe/go-spiffe/v2/workloadapi?tab=doc#X509ContextWatcher) to send updates (or errors) to clients.

```go
err = client.WatchX509Context(ctx, &x509Watcher{})
```
The watcher will be notified every time an SVID is updated or an error occurs.

It is possible to watch for JWT Bundles updates:
```go
err = client.WatchJWTBundles(ctx, &jwtWatcher{})
```

The watcher will be notified every time a JWT Bundle  is updated or an error occurs. 

## Building
Build the spiffe-watcher example:

```bash
cd examples/spiffe-watcher
go build
```

## Running
This example assumes the following preconditions:
- There is a SPIRE server and agent up and running.
- There is a Unix workload attestor configured.
- The trust domain is `example.org`
- The agent SPIFFE ID is `spiffe://example.org/host`.
- There is a `spiffe-watcher` user in the system.

### 1. Create the registration entry
Create the registration entry for the spiffe-watcher workload:
```bash
./spire-server entry create -spiffeID spiffe://example.org/spiffe-watcher \
                            -parentID spiffe://example.org/host \
                            -selector unix:user:spiffe-watcher
```

### 2. Start the workload
Start the spiffe-watcher with the `spiffe-watcher` user:
```bash
sudo -u spiffe-watcher ./spiffe-watcher
```

The watcher prints the SVID SPIFFE ID every time an SVID is updated.
 
```
SVID updated for "spiffe://example.org/spiffe-watcher":
-----BEGIN CERTIFICATE-----

FnFdqZr2XMrT
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----

gLI5JLc=
-----END CERTIFICATE-----

jwt bundle updated "example.org": {"keys":[{"kty":"EC","kid":"KULvTqUAs9SwuYGoO06ifavOQkA5Dkic","crv":"P-256","x":"WtHZ13-FO_B4SXhYbtXE-e7TmFl_txMOtY-Ls3jWPeE","y":"UNkGvC4MYOUXbgoHRCXGAtSTVE9zqXCkecjTB2cj9RA"}]}
jwt bundle updated "example.org": {"keys":[{"kty":"EC","kid":"KULvTqUAs9SwuYGoO06ifavOQkA5Dkic","
```
