diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..52cd20a6 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,32 @@ +# golang:1.19.2-alpine3.16 +ARG builderimage=golang@sha256:46752c2ee3bd8388608e41362964c84f7a6dffe99d86faeddc82d917740c5968 +# alpine:3.16.2 +ARG baseimage=alpine@sha256:1304f174557314a7ed9eddb4eab12fed12cb0cd9809e4c28f29af86979a3c870 + +# Build stage +FROM ${builderimage} as builder +RUN apk add build-base ncurses curl +ADD go.mod /galadriel/go.mod +WORKDIR /galadriel +RUN go mod download +ADD . /galadriel/ +RUN make build + +# Base image +FROM ${baseimage} AS base +RUN apk --no-cache add dumb-init +RUN mkdir -p /opt/galadriel/bin + +# Galadriel Server +FROM base AS galadriel-server +COPY --from=builder /galadriel/bin/galadriel-server /opt/galadriel/bin/galadriel-server +WORKDIR /opt/galadriel +ENTRYPOINT ["/usr/bin/dumb-init", "/opt/galadriel/bin/galadriel-server"] +CMD ["run"] + +# Galadriel Harvester +FROM base AS galadriel-harvester +COPY --from=builder /galadriel/bin/galadriel-harvester /opt/galadriel/bin/galadriel-harvester +WORKDIR /opt/galadriel +ENTRYPOINT ["/usr/bin/dumb-init", "/opt/galadriel/bin/galadriel-harvester"] +CMD ["run"] diff --git a/Makefile b/Makefile index a52cfee1..9e701a55 100644 --- a/Makefile +++ b/Makefile @@ -95,7 +95,7 @@ space := $(null) .PHONY: build -## Compile Go binaries for the Galadriel. +## Compiles all Galadriel binaries. build: bin/galadriel-harvester bin/galadriel-server # This is the master template for compiling Go binaries @@ -121,33 +121,33 @@ CONTAINER_EXEC := $(foreach exec,$(CONTAINER_OPTIONS),\ server-run: build ./bin/galadriel-server run -api-doc-build: - $(CONTAINER_EXEC) build -f doc/api/Dockerfile -t galadriel-api-doc:latest . - -## Build the API documentation for the Galadriel. -api-doc: api-doc-build - $(CONTAINER_EXEC) run --rm \ - --name galadriel-api-doc \ - -p 8000:8000 \ - --mount type=bind,source=${DIR}/spec/api,target=/app/api,readonly \ - galadriel-api-doc:latest - ## Runs the go unit tests. test: test-unit test-unit: go test -cover ./... -## Run unit tests with race detection. +## Runs unit tests with race detection. race-test: go test -cover -race ./... -## Generate the test coverage for the code with the Go tool. +## Generates the test coverage for the code with the Go tool. coverage: $(E)mkdir -p out/coverage go test -v -coverprofile ./out/coverage/coverage.out ./... && \ go tool cover -html=./out/coverage/coverage.out -o ./out/coverage/index.html +## Builds docker image for Galadriel Server. +docker-build-server: + docker build . --target galadriel-server --tag galadriel-server:latest + +## Builds docker image for Galadriel Harvester. +docker-build-harvester: + docker build . --target galadriel-harvester --tag galadriel-harvester:latest + +## Builds all docker images. +docker-build: docker-build-server docker-build-harvester + #------------------------------------------------------------------------ # Document file #------------------------------------------------------------------------ @@ -161,7 +161,7 @@ AUTHOR=HPE GREEN := $(shell tput -Txterm setaf 2) RESET := $(shell tput -Txterm sgr0) -TARGET_MAX_CHAR_NUM=20 +TARGET_MAX_CHAR_NUM=30 ## Shows help. help: diff --git a/cmd/harvester/cli/run.go b/cmd/harvester/cli/run.go index 0ab7b193..f5fd70ab 100644 --- a/cmd/harvester/cli/run.go +++ b/cmd/harvester/cli/run.go @@ -78,6 +78,7 @@ func LoadConfig(cmd *cobra.Command) (*harvester.Config, error) { } logrus.SetLevel(logLevel) + logrus.SetOutput(os.Stdout) hc.AccessToken = token diff --git a/cmd/server/cli/run.go b/cmd/server/cli/run.go index 91bcab03..d69f00e3 100644 --- a/cmd/server/cli/run.go +++ b/cmd/server/cli/run.go @@ -72,7 +72,9 @@ func LoadConfig(cmd *cobra.Command) (*server.Config, error) { if err != nil { return nil, err } + logrus.SetLevel(logLevel) + logrus.SetOutput(os.Stdout) return sc, nil } diff --git a/demo/.gitignore b/demo/.gitignore new file mode 100644 index 00000000..f58aaaf7 --- /dev/null +++ b/demo/.gitignore @@ -0,0 +1,3 @@ +**/spire/.data +**/spire/conf/agent/root_ca.crt +bin/ diff --git a/demo/0-setup.sh b/demo/0-setup.sh new file mode 100755 index 00000000..7a601cec --- /dev/null +++ b/demo/0-setup.sh @@ -0,0 +1,31 @@ +#!/bin/bash +set -e + +SPIRE_VERSION=${SPIRE_VERSION:=v1.4.4} + +cwd=$(pwd) +temp_clone=/tmp/spire-${SPIRE_VERSION} +mkdir -p ./bin + +cleanup() { + rm -rf ${temp_clone} + exit +} +trap cleanup EXIT + +# Build SPIRE +git clone https://github.com/spiffe/spire.git --single-branch --branch ${SPIRE_VERSION} -c advice.detachedHead=false ${temp_clone} +(cd ${temp_clone}; \ + make build; \ + cp bin/spire-server bin/spire-agent ${cwd}/bin/) + +# Build Galadriel +(cd ../; \ + make build; \ + cp ./bin/galadriel-server ./bin/galadriel-harvester ${cwd}/bin/) + +# Build greeter demo +(cd greeter; \ + CGO_ENABLED=0 go build -o ../bin/greeter-server ./cmd/greeter-server/main.go; + CGO_ENABLED=0 go build -o ../bin/greeter-client ./cmd/greeter-client/main.go) + diff --git a/demo/1-run-spire-servers.sh b/demo/1-run-spire-servers.sh new file mode 100755 index 00000000..ce1bfa4b --- /dev/null +++ b/demo/1-run-spire-servers.sh @@ -0,0 +1,8 @@ +#!/bin/bash +set -e +source util.sh + +one ./bin/spire-server run -config one.org/spire/conf/server/server.conf +two ./bin/spire-server run -config two.org/spire/conf/server/server.conf + +wait diff --git a/demo/2-run-spire-agents.sh b/demo/2-run-spire-agents.sh new file mode 100755 index 00000000..611e97b0 --- /dev/null +++ b/demo/2-run-spire-agents.sh @@ -0,0 +1,20 @@ +#!/bin/bash +set -e +source util.sh + +spire_one_socket=/tmp/one.org/spire-server/private/api.sock +spire_two_socket=/tmp/two.org/spire-server/private/api.sock + +# Get current CA from SPIRE Server +./bin/spire-server bundle show -socketPath ${spire_one_socket} > ./one.org/spire/conf/agent/root_ca.crt +./bin/spire-server bundle show -socketPath ${spire_two_socket} > ./two.org/spire/conf/agent/root_ca.crt + +# Get join tokens +token_one=$(./bin/spire-server token generate -socketPath ${spire_one_socket} -spiffeID spiffe://one.org/my-agent | grep Token | cut -c 8-100) +token_two=$(./bin/spire-server token generate -socketPath ${spire_two_socket} -spiffeID spiffe://two.org/my-agent | grep Token | cut -c 8-100) + +# Start agents +one ./bin/spire-agent run -config ./one.org/spire/conf/agent/agent.conf -joinToken ${token_one} +two ./bin/spire-agent run -config ./two.org/spire/conf/agent/agent.conf -joinToken ${token_two} + +wait diff --git a/demo/3-run-galadriel-server.sh b/demo/3-run-galadriel-server.sh new file mode 100755 index 00000000..c01ace31 --- /dev/null +++ b/demo/3-run-galadriel-server.sh @@ -0,0 +1,5 @@ +#!/bin/bash +set -e + +# Run Galadriel Server +./bin/galadriel-server run --config ./galadriel-server/server.conf diff --git a/demo/4-create-members.sh b/demo/4-create-members.sh new file mode 100755 index 00000000..33c0ad53 --- /dev/null +++ b/demo/4-create-members.sh @@ -0,0 +1,6 @@ +#!/bin/bash +set -e + +./bin/galadriel-server create member --trustDomain one.org +./bin/galadriel-server create member --trustDomain two.org +./bin/galadriel-server create relationship -a one.org -b two.org diff --git a/demo/5-run-harvesters.sh b/demo/5-run-harvesters.sh new file mode 100755 index 00000000..995b8022 --- /dev/null +++ b/demo/5-run-harvesters.sh @@ -0,0 +1,11 @@ +#!/bin/bash +set -e +source util.sh + +token_one=$(./bin/galadriel-server generate token -t one.org | cut -c 15-100) +token_two=$(./bin/galadriel-server generate token -t two.org | cut -c 15-100) + +one ./bin/galadriel-harvester run --config ./one.org/harvester/harvester.conf --token ${token_one} +two ./bin/galadriel-harvester run --config ./two.org/harvester/harvester.conf --token ${token_two} + +wait diff --git a/demo/6-create-entries.sh b/demo/6-create-entries.sh new file mode 100755 index 00000000..a4835259 --- /dev/null +++ b/demo/6-create-entries.sh @@ -0,0 +1,21 @@ +#!/bin/bash +set -e + +spire_one_socket=/tmp/one.org/spire-server/private/api.sock +spire_two_socket=/tmp/two.org/spire-server/private/api.sock + +# Create entry for greeter-server in one.org +./bin/spire-server entry create \ + -socketPath ${spire_one_socket} \ + -spiffeID spiffe://one.org/greeter-server \ + -parentID spiffe://one.org/my-agent \ + -selector unix:uid:$(id -u) \ + -federatesWith two.org + +# Create entry for greeter-client in two.org +./bin/spire-server entry create \ + -socketPath ${spire_two_socket} \ + -spiffeID spiffe://two.org/greeter-client \ + -parentID spiffe://two.org/my-agent \ + -selector unix:uid:$(id -u) \ + -federatesWith one.org diff --git a/demo/7-run-greeter.sh b/demo/7-run-greeter.sh new file mode 100755 index 00000000..1f692239 --- /dev/null +++ b/demo/7-run-greeter.sh @@ -0,0 +1,17 @@ +#!/bin/bash +set -e +source util.sh + +agent_one_socket=/tmp/one.org/spire-agent/private/api.sock +agent_two_socket=/tmp/two.org/spire-agent/private/api.sock + +cleanup() { + pkill greeter-server greeter-client +} +trap cleanup EXIT + +# Run greeter server and client +server ./bin/greeter-server --workloadapi unix://${agent_one_socket}; sleep 5 +client ./bin/greeter-client --workloadapi unix://${agent_two_socket} + +wait diff --git a/demo/README.md b/demo/README.md new file mode 100644 index 00000000..e9a14551 --- /dev/null +++ b/demo/README.md @@ -0,0 +1,32 @@ +# Demo + +The following demo script shows how to setup two simple SPIRE deployments and have them federated using Galadriel. + +![Demo diagram](diagram.png "Demo diagram") + +## Requirements + +This demo only requires a `git` client and the `make` command properly installed in the system. + +Tested on macOS Mojave and Ventura, and Debian Bullseye. + +## Steps + +Run the following scripts in order: + +- `0-setup.sh`: This will make sure you have all SPIRE, Galadriel and the sample application binaries. +- `1-run-spire-servers.sh`: Runs two SPIRE Server instances, `one.org` and `two.org`. +- `2-run-spire-agents.sh`: Runs and attests two SPIRE Agent instances using join tokens. +- `3-run-galadriel-server.sh`: Runs an instance of the Galadriel Server. +- `4-create-members.sh`: Creates the member entities for both Trust Domains in Galadriel, and setups a federation relationship between them. +- `5-run-harvester.sh`: Runs two Galadriel Harvesters connected to the Galadriel Server and to each SPIRE Server. +- `6-create-entries.sh`: Creates the federated entries needed to attest the sample `greeter` application server and client. +- `7-run-greeter.sh`: Runs the greeter server and client. + +The `greeter` server fetches its SVID from the SPIRE Agent serving `one.org`, and uses this credential to listen for incoming connections. + +The `greeter` client fetches its SVID from the SPIRE Agent serving `two.org`, and uses this credential to connect to the server. + +## Cleanup + +Run `x-cleanup.sh` to remove from the system all the SPIRE data created by this demo. \ No newline at end of file diff --git a/demo/diagram.png b/demo/diagram.png new file mode 100644 index 00000000..72666158 Binary files /dev/null and b/demo/diagram.png differ diff --git a/demo/galadriel-server/server.conf b/demo/galadriel-server/server.conf new file mode 100644 index 00000000..7d5a88fa --- /dev/null +++ b/demo/galadriel-server/server.conf @@ -0,0 +1,5 @@ +server { + listen_address = "localhost" + listen_port = "8085" + socket_path = "/tmp/galadriel-server/api.sock" +} diff --git a/demo/greeter/cmd/greeter-client/main.go b/demo/greeter/cmd/greeter-client/main.go new file mode 100644 index 00000000..b2000dec --- /dev/null +++ b/demo/greeter/cmd/greeter-client/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "context" + "flag" + "log" + "os" + "time" + + "github.com/spiffe/go-spiffe/v2/spiffegrpc/grpccredentials" + "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" + "github.com/spiffe/go-spiffe/v2/workloadapi" + "google.golang.org/grpc" + "google.golang.org/grpc/examples/helloworld/helloworld" + "google.golang.org/grpc/peer" +) + +func main() { + var serverAddr string + var wlapiAddr string + + flag.StringVar(&serverAddr, "server", "localhost:8080", "host:port of the server") + flag.StringVar(&wlapiAddr, "workloadapi", "unix:///tmp/spire-agent/public/api.sock", "workload endpoint socket URI, starting with tcp:// or unix:// scheme") + flag.Parse() + + log.SetOutput(os.Stdout) + log.Println("Starting up...") + log.Println("Server Address:", serverAddr) + + ctx := context.Background() + + // Get credentials from the Workload API + log.Println("Calling Workload API...") + timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*5) + defer cancel() + + opts := workloadapi.WithClientOptions(workloadapi.WithAddr(wlapiAddr)) + source, err := workloadapi.NewX509Source(timeoutCtx, opts) + if err != nil { + log.Fatal(err) + } + defer source.Close() + creds := grpccredentials.MTLSClientCredentials(source, source, tlsconfig.AuthorizeAny()) + + // Establish gRPC connection to the server + client, err := grpc.DialContext(timeoutCtx, serverAddr, grpc.WithTransportCredentials(creds)) + if err != nil { + log.Fatal(err) + } + defer client.Close() + + // Make calls to the greeter server + greeterClient := helloworld.NewGreeterClient(client) + + const interval = time.Second * 10 + log.Printf("Issuing requests every %s...", interval) + for { + issueRequest(ctx, greeterClient) + time.Sleep(interval) + } +} + +func issueRequest(ctx context.Context, c helloworld.GreeterClient) { + p := new(peer.Peer) + resp, err := c.SayHello(ctx, &helloworld.HelloRequest{ + Name: "SPIFFE community", + }, grpc.Peer(p)) + if err != nil { + log.Printf("Failed to say hello: %v", err) + return + } + + serverID := "UNKNOWN-SERVER" + if peerID, ok := grpccredentials.PeerIDFromPeer(p); ok { + serverID = peerID.String() + } + + log.Printf("%s said %q", serverID, resp.Message) +} diff --git a/demo/greeter/cmd/greeter-server/main.go b/demo/greeter/cmd/greeter-server/main.go new file mode 100644 index 00000000..dd5862bc --- /dev/null +++ b/demo/greeter/cmd/greeter-server/main.go @@ -0,0 +1,75 @@ +package main + +import ( + "context" + "flag" + "fmt" + "log" + "net" + "os" + "time" + + "github.com/spiffe/go-spiffe/v2/spiffegrpc/grpccredentials" + "github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig" + "github.com/spiffe/go-spiffe/v2/workloadapi" + "google.golang.org/grpc" + "google.golang.org/grpc/examples/helloworld/helloworld" +) + +func main() { + var bindAddr string + var wlapiAddr string + + flag.StringVar(&bindAddr, "bind", "localhost:8080", "host:port of the server") + flag.StringVar(&wlapiAddr, "workloadapi", "unix:///tmp/spire-agent/public/api.sock", "workload endpoint socket URI, starting with tcp:// or unix:// scheme") + flag.Parse() + + log.SetOutput(os.Stdout) + log.Println("Starting up...") + + ctx := context.Background() + + // Get credentials from the Workload API + log.Println("Calling Workload API...") + timeoutCtx, cancel := context.WithTimeout(ctx, time.Second*5) + defer cancel() + + opts := workloadapi.WithClientOptions(workloadapi.WithAddr(wlapiAddr)) + source, err := workloadapi.NewX509Source(timeoutCtx, opts) + if err != nil { + log.Fatal(err) + } + defer source.Close() + creds := grpccredentials.MTLSServerCredentials(source, source, tlsconfig.AuthorizeAny()) + + // Listens for requests + listener, err := net.Listen("tcp", bindAddr) + if err != nil { + log.Fatal(err) + } + + server := grpc.NewServer(grpc.Creds(creds)) + helloworld.RegisterGreeterServer(server, greeter{}) + + log.Println("Serving on", listener.Addr()) + if err := server.Serve(listener); err != nil { + log.Fatal(err) + } + +} + +type greeter struct { + helloworld.UnimplementedGreeterServer +} + +func (greeter) SayHello(ctx context.Context, req *helloworld.HelloRequest) (*helloworld.HelloReply, error) { + clientID := "UNKNOWN-CLIENT" + if peerID, ok := grpccredentials.PeerIDFromContext(ctx); ok { + clientID = peerID.String() + } + + log.Printf("%s has requested that I say hello to %q...", clientID, req.Name) + return &helloworld.HelloReply{ + Message: fmt.Sprintf("On behalf of %s, hello %s!", clientID, req.Name), + }, nil +} diff --git a/demo/greeter/go.mod b/demo/greeter/go.mod new file mode 100644 index 00000000..62b93d4c --- /dev/null +++ b/demo/greeter/go.mod @@ -0,0 +1,21 @@ +module greeter + +go 1.17 + +require ( + github.com/spiffe/go-spiffe/v2 v2.0.0-beta.10 + google.golang.org/grpc v1.50.1 + google.golang.org/grpc/examples v0.0.0-20211001222728-09970207abb5 +) + +require ( + github.com/golang/protobuf v1.5.2 // indirect + github.com/zeebo/errs v1.2.2 // indirect + golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 // indirect + golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect + golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 // indirect + golang.org/x/text v0.3.3 // indirect + google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 // indirect + google.golang.org/protobuf v1.27.1 // indirect + gopkg.in/square/go-jose.v2 v2.4.1 // indirect +) diff --git a/demo/greeter/go.sum b/demo/greeter/go.sum new file mode 100644 index 00000000..ebd012dc --- /dev/null +++ b/demo/greeter/go.sum @@ -0,0 +1,125 @@ +cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= +github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= +github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= +github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= +github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= +github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= +github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= +github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= +github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= +github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= +github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= +github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= +github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/spiffe/go-spiffe/v2 v2.0.0-beta.10 h1:UXfGMp27MlQcYCAVRl21+cZrbKXMLsFmMXam5W3qBIA= +github.com/spiffe/go-spiffe/v2 v2.0.0-beta.10/go.mod h1:TEfgrEcyFhuSuvqohJt6IxENUNeHfndWCCV1EX7UaVk= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/zeebo/errs v1.2.2 h1:5NFypMTuSdoySVTqlNs1dEoU21QVamMQJxW/Fii5O7g= +github.com/zeebo/errs v1.2.2/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= +golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= +golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4 h1:myAQVi0cGEoqQVR5POX+8RR2mrocKqNN1hmeMqhX27k= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= +golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= +google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= +google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98 h1:LCO0fg4kb6WwkXQXRQQgUYsFeFb5taTX5WAx5O/Vt28= +google.golang.org/genproto v0.0.0-20200806141610-86f49bd18e98/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= +google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= +google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= +google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= +google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= +google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= +google.golang.org/grpc v1.50.1 h1:DS/BukOZWp8s6p4Dt/tOaJaTQyPyOoCcrjroHuCeLzY= +google.golang.org/grpc v1.50.1/go.mod h1:ZgQEeidpAuNRZ8iRrlBKXZQP1ghovWIVhdJRyCDK+GI= +google.golang.org/grpc/examples v0.0.0-20201130180447-c456688b1860/go.mod h1:Ly7ZA/ARzg8fnPU9TyZIxoz33sEUuWX7txiqs8lPTgE= +google.golang.org/grpc/examples v0.0.0-20211001222728-09970207abb5 h1:k1HwCrvyzmToHY1nDSfCGU63gsShFOG46m7dks5rdRw= +google.golang.org/grpc/examples v0.0.0-20211001222728-09970207abb5/go.mod h1:gID3PKrg7pWKntu9Ss6zTLJ0ttC0X9IHgREOCZwbCVU= +google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= +google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= +google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= +google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= +google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= +google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= +google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/square/go-jose.v2 v2.4.1 h1:H0TmLt7/KmzlrDOpa1F+zr0Tk90PbJYBfsVUmRLrf9Y= +gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= +gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= diff --git a/demo/one.org/harvester/harvester.conf b/demo/one.org/harvester/harvester.conf new file mode 100644 index 00000000..c6111e4c --- /dev/null +++ b/demo/one.org/harvester/harvester.conf @@ -0,0 +1,5 @@ +harvester { + spire_socket_path = "/tmp/one.org/spire-server/private/api.sock" + server_address = "localhost:8085" + bundle_updates_interval = "5s" +} diff --git a/demo/one.org/spire/conf/agent/agent.conf b/demo/one.org/spire/conf/agent/agent.conf new file mode 100644 index 00000000..f5b65f73 --- /dev/null +++ b/demo/one.org/spire/conf/agent/agent.conf @@ -0,0 +1,25 @@ +agent { + data_dir = "./one.org/spire/.data/agent" + log_level = "DEBUG" + server_address = "127.0.0.1" + server_port = "8081" + socket_path = "/tmp/one.org/spire-agent/private/api.sock" + trust_bundle_path = "./one.org/spire/conf/agent/root_ca.crt" + trust_domain = "one.org" +} + +plugins { + NodeAttestor "join_token" { + plugin_data { + } + } + KeyManager "disk" { + plugin_data { + directory = "./one.org/spire/.data/agent" + } + } + WorkloadAttestor "unix" { + plugin_data { + } + } +} diff --git a/demo/one.org/spire/conf/server/server.conf b/demo/one.org/spire/conf/server/server.conf new file mode 100644 index 00000000..2476de3b --- /dev/null +++ b/demo/one.org/spire/conf/server/server.conf @@ -0,0 +1,32 @@ +server { + bind_address = "127.0.0.1" + bind_port = "8081" + socket_path = "/tmp/one.org/spire-server/private/api.sock" + trust_domain = "one.org" + data_dir = "./one.org/spire/.data/server" + log_level = "DEBUG" + ca_ttl = "3m" + ca_subject { + country = ["US"] + organization = ["SPIFFE"] + common_name = "" + } +} + +plugins { + DataStore "sql" { + plugin_data { + database_type = "sqlite3" + connection_string = "./one.org/spire/.data/server/datastore.sqlite3" + } + } + + NodeAttestor "join_token" { + plugin_data { + } + } + + KeyManager "memory" { + plugin_data = {} + } +} diff --git a/demo/two.org/harvester/harvester.conf b/demo/two.org/harvester/harvester.conf new file mode 100644 index 00000000..6ebe3353 --- /dev/null +++ b/demo/two.org/harvester/harvester.conf @@ -0,0 +1,5 @@ +harvester { + spire_socket_path = "/tmp/two.org/spire-server/private/api.sock" + server_address = "localhost:8085" + bundle_updates_interval = "5s" +} diff --git a/demo/two.org/spire/conf/agent/agent.conf b/demo/two.org/spire/conf/agent/agent.conf new file mode 100644 index 00000000..921b92dd --- /dev/null +++ b/demo/two.org/spire/conf/agent/agent.conf @@ -0,0 +1,25 @@ +agent { + data_dir = "./two.org/spire/.data/agent" + log_level = "DEBUG" + server_address = "127.0.0.1" + server_port = "8082" + socket_path = "/tmp/two.org/spire-agent/private/api.sock" + trust_bundle_path = "./two.org/spire/conf/agent/root_ca.crt" + trust_domain = "two.org" +} + +plugins { + NodeAttestor "join_token" { + plugin_data { + } + } + KeyManager "disk" { + plugin_data { + directory = "./two.org/spire/.data/agent" + } + } + WorkloadAttestor "unix" { + plugin_data { + } + } +} diff --git a/demo/two.org/spire/conf/server/server.conf b/demo/two.org/spire/conf/server/server.conf new file mode 100644 index 00000000..39d0702f --- /dev/null +++ b/demo/two.org/spire/conf/server/server.conf @@ -0,0 +1,32 @@ +server { + bind_address = "127.0.0.1" + bind_port = "8082" + socket_path = "/tmp/two.org/spire-server/private/api.sock" + trust_domain = "two.org" + data_dir = "./two.org/spire/.data/server" + log_level = "DEBUG" + ca_ttl = "3m" + ca_subject { + country = ["US"] + organization = ["SPIFFE"] + common_name = "" + } +} + +plugins { + DataStore "sql" { + plugin_data { + database_type = "sqlite3" + connection_string = "./two.org/spire/.data/server/datastore.sqlite3" + } + } + + NodeAttestor "join_token" { + plugin_data { + } + } + + KeyManager "memory" { + plugin_data = {} + } +} diff --git a/demo/util.sh b/demo/util.sh new file mode 100644 index 00000000..3adc0a66 --- /dev/null +++ b/demo/util.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +cyan=$(tput setaf 6) +yellow=$(tput setaf 3) +green=$(tput setaf 2) +purple=$(tput setaf 5) +norm=$(tput sgr0) + +one() { + colorize $cyan "ONE.ORG" ${@:1} +} + +two() { + colorize $yellow "TWO.ORG" ${@:1} +} + +server() { + colorize $green "SERVER" ${@:1} +} + +client() { + colorize $purple "CLIENT" ${@:1} +} + +# Usage: colorize +colorize() { + color=$1 + prefix=$2 + cmd=${@:3} + eval "${cmd} | sed -e 's/^/${color}[${prefix}] /' -e 's/$/${norm}/' &" +} diff --git a/demo/x-cleanup.sh b/demo/x-cleanup.sh new file mode 100755 index 00000000..f81e1d2d --- /dev/null +++ b/demo/x-cleanup.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +rm -rf ./one.org/spire/.data +rm -rf ./two.org/spire/.data +rm -rf /tmp/one.org +rm -rf /tmp/two.org