V3 of the auth service API used for Ambassador Edge Stack has been released as part of Emissary-ingress/Edge-Stack version 2.3.0
. Version 2.3.0
supports both the v2
and the v3
API, whereas as of Emissary-ingress/Edge-Stack version 3.0.0
only the v3
transport protocol is supported.
Please see the v2 service if you are looking for an example you can use for Emissary-ingress/Edge-Stack versions prior to 2.3.0
.
Example service for authorization in Envoy over gRPC using transport protocol v3
This is an example service for performing operations on requests. It is meant to be used with
an Ambassador Edge Stack External Filter
.
When requests pass through this filter it will:
- Read and log all of the headers.
- If the
sleepfor
header is present, it will parse it's value and sleep for that ammount of time to simulate a timeout or delayed response form the service. - If the
deny-me
header is present, it will deny the request. - If the
url.path
of the request is/deny-me/
it will deny the request. - Rewrite the value of the
v3alphaOverwrite
header. - Append a new value to the
v3alphaAppend
header.
You can find a list of status codes to be used with this external filter at the following two links:
git clone
this repository.
run go mod tidy
run docker build -t {DOCKER_HUB_USERNAME}/{NAME_FOR_IMAGE}:{VERSION} .
- I've already built and deployed an image you can use instead:
alicewasko/grpcauth-v3:0.1
Install Ambassador Edge Stack to your Kubernetes cluster.
Create a new file Authv3.yaml
and add the following information to it:
Make sure to replace {YOUR_IMAGE_HERE}
with the image you built, or the prebuilt image I provided above
---
apiVersion: v1
kind: Service
metadata:
name: grpc-auth
spec:
type: ClusterIP
selector:
app: grpc-auth
ports:
- port: 3000
name: http-grpc-auth
targetPort: http-api
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: grpc-auth
spec:
replicas: 1
strategy:
type: RollingUpdate
selector:
matchLabels:
app: grpc-auth
template:
metadata:
labels:
app: grpc-auth
spec:
containers:
- name: grpc-auth
image: alicewasko/grpcauth-v3:0.1
imagePullPolicy: Always
ports:
- name: http-api
containerPort: 3000
resources:
limits:
cpu: "0.1"
memory: 100Mi
Create a new file AuthFilterv3.yaml
and add the following to it:
This will create a filter for us, configure that filter to run on all requests, and configure that filter to send requests to this service.
---
apiVersion: getambassador.io/v3alpha1
kind: Filter
metadata:
name: ext-filter-v3
spec:
External:
proto: "grpc"
protocol_version: v3
auth_service: "grpc-auth.default:3000"
allowed_request_headers:
- "v3alphaOverwrite"
- "v3alphaAppend"
---
apiVersion: getambassador.io/v3alpha1
kind: FilterPolicy
metadata:
name: ext-filter-v3
spec:
rules:
- host: "*"
path: /**
filters:
- name: ext-filter-v3
Apply the Service, Deployment, and Filter configuration:
kubectl apply -f Authv3.yaml
kubectl apply -f AuthFilterv3.yaml
Deploy the Quote of the Moment service that is part of the Ambassador Edge Stack
quick start guide.
This will deploy an additional service that we can send requests to in order to test our filter service. This will deploy the quote service and make it reachable on the /quote/
path.
Create a QuoteDeployment.yaml
file:
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: quote-mapping
spec:
hostname: "*"
prefix: /quote/
service: quote
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: quote
spec:
replicas: 1
selector:
matchLabels:
app: quote
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: quote
spec:
containers:
- name: backend
image: docker.io/datawire/quote:0.5.0
ports:
- name: http
containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: quote
annotations:
a8r.io/description: "Quote of the moment service"
a8r.io/owner: "No owner"
a8r.io/chat: "#ambassador"
a8r.io/bugs: "https://github.com/datawire/quote/issues"
a8r.io/documentation: "https://github.com/datawire/quote/blob/master/README.md"
a8r.io/repository: "https://github.com/datawire/quote"
a8r.io/support: "http://d6e.co/slack"
a8r.io/runbook: "https://github.com/datawire/quote/blob/master/README.md"
a8r.io/incidents: "https://github.com/datawire/quote/issues"
a8r.io/dependencies: "None"
spec:
ports:
- name: http
port: 80
targetPort: 8080
selector:
app: quote
Apply the quote service and it's mapping.
kubectl apply -f QuoteDeployment.yaml
-
Grab the IP of your Ambassador service:
kubectl get svc -A
- Look for the
ambassador
service that hasType: LoadBalancer
and use itsExternal IP
:
-
Make some requests to the quote service. Our external filter will run this service on the requests before they get sent off to the quote service. The quote service has a
/debug/
endpoint which will print out all the headers for incomming requests so we can validate whether or not our service is working.
-
curl -kv https://{YOUR_AMBASSADOR_IP}/quote/debug/ -H "v3alphaOverwrite: test" -H "v3alphaAppend: test"
- You Should see that the value of the
v3alphaOverwrite
header that we passed was changed - The value of the
v3alphaAppend
header should also have a new value along with the value you passed
- You Should see that the value of the
-
curl -kv https://{YOUR_AMBASSADOR_IP}/quote/debug/ -H "deny-me: true"
- You should see an error is returned since the request was denied by our service
-
curl -kv https://{YOUR_AMBASSADOR_IP}/quote/debug/ -H "sleepfor: 2"
- You should see a 2 second delay before getting the reply from the Quote service since we told the filter service to sleep for 2 seconds.
This service will log information about the requests it processes. You can grab the logs using kubectl
to view each request that came in:
- The path of the incomming requests
- All of the request's headers are logged
- What action was taken for the request (Allow/Deny/Error)