Skip to content

Commit

Permalink
feat: Simple Authentication for webhook related event sources. Closes #…
Browse files Browse the repository at this point in the history
…821 (#826)

* feat: Simple Authentication for webhook related event sources

* minor

* minor again
  • Loading branch information
whynowy committed Aug 10, 2020
1 parent fa33eb3 commit bfbbd33
Show file tree
Hide file tree
Showing 11 changed files with 503 additions and 311 deletions.
17 changes: 16 additions & 1 deletion api/event-source.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 26 additions & 1 deletion api/event-source.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion api/openapi-spec/swagger.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 46 additions & 0 deletions docs/webhook-authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Webhook Authentication

![alpha](assets/alpha.svg)

> v1.0 and after
For `webhook` event source, if you want to get your endpoint protected from
unauthorized accessing, you can specify `authSecret` to the spec, which is a K8s
secret key selector.

This simple authentication approach also works for `webhook` extended event
sources, if that event source does not have a built in authenticator.

Firstly, create a k8s secret containing your token.

```sh
echo -n 'af3qqs321f2ddwf1e2e67dfda3fs' > ./token.txt

kubectl create secret generic my-webhook-token --from-file=my-token=./token.txt
```

Then add `authSecret` to your `webhook` EventSource.

```yaml
apiVersion: argoproj.io/v1alpha1
kind: EventSource
metadata:
name: webhook
spec:
webhook:
example:
port: "12000"
endpoint: /example
method: POST
authSecret:
name: my-webhook-token
key: my-token
```

Now you can authenticate your webhook endpoint with the configured token.

```sh
TOKEN="Bearer af3qqs321f2ddwf1e2e67dfda3fs"

curl -X POST -H "Authorization: $TOKEN" -d "{your data}" http://xxxxx:12000/example
```
24 changes: 23 additions & 1 deletion eventsources/common/webhook/webhook.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import (
"context"
"fmt"
"net/http"
"strings"

"github.com/gorilla/mux"
"go.uber.org/zap"
Expand Down Expand Up @@ -104,7 +105,28 @@ func startServer(router Router, controller *Controller) {
if r == nil {
r = handler.NewRoute().Name(routeName)
r = r.Path(route.Context.Endpoint)
r.HandlerFunc(router.HandleRoute)
r.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
if route.Context.AuthSecret != nil {
token, err := common.GetSecretFromVolume(route.Context.AuthSecret)
if err != nil {
route.Logger.Errorw("failed to get auth secret from volume", "error", err)
common.SendInternalErrorResponse(writer, "Error loading auth token")
return
}
authHeader := request.Header.Get("Authorization")
if !strings.HasPrefix(authHeader, "Bearer ") {
route.Logger.Error("invalid auth header")
common.SendErrorResponse(writer, "Invalid Authorization Header")
return
}
if strings.TrimPrefix(authHeader, "Bearer ") != token {
route.Logger.Error("invalid auth token")
common.SendErrorResponse(writer, "Invalid Auth token")
return
}
}
router.HandleRoute(writer, request)
})
}

healthCheckRouteName := route.Context.Port + "/health"
Expand Down

0 comments on commit bfbbd33

Please sign in to comment.