Table of Contents |
---|
Authentication with Emco
EMCO uses Istio and other open source solutions to provide Multi-tenancy solution leveraging Istio Authorization and Authentication frameworks. This is achieved without adding any logic in EMCO microservices. Authentication for the EMCO users are done at the Isito Gateway, where all the traffic enters the cluster. Istio along with autherservice (istio ecosystem project) enables request-level authentication with JSON Web Token (JWT) validation. This can be achieved using a custom authentication provider or any OpenID Connect providers like KeyCloak, Auth0 etc.
In ONAP4K8s no security (Mutual TLS, Authentication and Authorization) and traffic management (Load balancing, Circuit breaking, Traffic control & rate limiting) are not part of the ONAP4K8s micro-services. Also, log collection, metrics collection and distributed tracing for troubleshooting are all not part of the ONAP4K8s micro-services. CNCF architecture is used for these to improve productivity and reduce the errors.
To achieve the above goals ISTIO is used by ONAP4K8s for providing following:
...
Authservice is an entity that works along side with Envoy proxy. It is used to work with external IAM systems (OAUTH2). Many Enterprises have their own OAUTH2 server for authenticating users and provide roles. ONAP4K8s uses Authservice from ISTIO-ingress proxy to talk to multiple OAUTH2 servers, one belonging to each project (Enterprise).
...
used to work with external IAM systems (OAUTH2). Many Enterprises have their own OAUTH2 server for authenticating users and provide roles. ONAP4K8s along with Istio-ingress and Authservice use single or multiple OAUTH2 servers, one belonging to each project (Enterprise).
draw.io Diagram | ||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
Authentication Flow with OIDC, Istio Ingress Gateway and Authservice
PlantUML Macro | ||
---|---|---|
| ||
@startuml
User -> IstioIngress: Access EMCO Rest API's
IstioIngress --> Authservice: Forwared
Authservice -> User: Redirect to User Browser with Keycloak URL
User -> Keycloak: User Browser taken to Keycloack URL
Keycloak -> User: Login Page user prompted to enter credentials
Keycloak -> User: Redirect to User Browser with Authentication code
User -> IstioIngress: Access EMCO Rest API's with authentication code
IstioIngress --> Authservice: Forwarded
Authservice -> Keycloak: Exchange authentication code for access token
Keycloak -> Authservice: Token
Authservice -> User: Redirect to original URL along with token
User -> IstioIngress: Access original URL with token
IstioIngress -> EMCOv2API: Verify token & allow access
@enduml |
Authorization with Emco
Emco uses Istio's AuthorizationPolicy resource to manage authorizations. See at the end of this post for example of Authorization policies.
Steps for setting up ONAP4K8s with Istio + Authservice
...
Code Block | ||||
---|---|---|---|---|
| ||||
stioctl kube-inject -f ovn4k8sdb.yaml | kubectl apply -f - istioctl kube-inject -f ovn4k8s.yaml | kubectl apply -f - kubectl create -n istio-system secret tls emco-credential --key=v2.key --cert=v2.crt |
...
Gateway
Code Block | ||||
---|---|---|---|---|
| ||||
$ kubectl create -n istio-system secret tls emco-credential --key=v2.key --cert=v2.crt apiVersion: networking.istio.io/v1alpha3 kind: Gateway metadata: name: emco-gateway namespace: istio-system spec: selector: istio: ingressgateway # use Istio default gateway implementation servers: - port: number: 80 name: http protocol: HTTP hosts: - "*" - port: number: 443 name: https protocol: HTTPS tls: mode: SIMPLE credentialName: emco-credential hosts: - "*" |
...
Virtual service
Code Block | ||||
---|---|---|---|---|
| ||||
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: orchestrator namespace: emco spec: hosts: - "*" gateways: - emco-gateway.istio-system.svc.cluster.local http: - match: - uri: prefix: /v2/oauth - uri: prefix: /v2 route: - destination: port: number: 9015 host: orchestrator |
Make sure the EMCO service is accessible through istio ingress gateway at this point. [https://<Istio Ingress service IP Address:port>/v2/projects]
...
Istio Policy
Code Block | ||||
---|---|---|---|---|
| ||||
apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "emco-authn-policy" namespace: istio-system spec: origins: - jwt: issuer: "https://<Keycloak IP Address:port>/auth/realms/enterprise1" jwksUri: "http://<Keycloak IP Address:port>/auth/realms/enterprise1/protocol/openid-connect/certs" principalBinding: USE_ORIGIN |
...
Authservice Setup in Istio Ingress-gateway
...
Authservice
...
Configmap
The following example shows how to setup authservice with keycloak.
...
Code Block | ||||
---|---|---|---|---|
| ||||
$ kubectl edit deployments istio-ingressgateway -n istio-system Under containers section add: - name: authservice image: adrianlzt/authservice:0.3.1-d3cd2d498169 imagePullPolicy: Always ports: - containerPort: 10003 volumeMounts: - name: emco-authservice-configmap-volume mountPath: /etc/authservice In the volumes section add: - name: emco-authservice-configmap-volume configMap: name: emco-authservice-configmap |
...
EnvoyFilter Resource for authservice
Code Block | ||||
---|---|---|---|---|
| ||||
# # Add the ext_authz filter to the istio-ingressgateway Envoy filter chain. # Configure the ext_authz filter to ask the authservice about every incoming request # via GRPC. For every incoming request, the authservice will decide to either allow # the request and add tokens as headers, or will cause the response to redirect for # authentication. # --- apiVersion: networking.istio.io/v1alpha3 kind: EnvoyFilter metadata: name: sidecar-token-service-filter-for-ingress namespace: istio-system spec: workloadSelector: labels: istio: ingressgateway app: istio-ingressgateway configPatches: - applyTo: HTTP_FILTER match: context: GATEWAY listener: filterChain: filter: name: "envoy.http_connection_manager" subFilter: name: "envoy.filters.http.jwt_authn" patch: operation: INSERT_BEFORE value: name: envoy.ext_authz config: stat_prefix: ext_authz grpc_service: envoy_grpc: cluster_name: ext_authz timeout: 10s # Timeout for the entire request (including authcode for token exchange with the IDP) - applyTo: CLUSTER match: context: ANY cluster: {} # this line is required starting in istio 1.4.0 patch: operation: ADD value: name: ext_authz connect_timeout: 5s # This timeout controls the initial TCP handshake timeout - not the timeout for the entire request type: LOGICAL_DNS lb_policy: ROUND_ROBIN http2_protocol_options: {} load_assignment: cluster_name: ext_authz endpoints: - lb_endpoints: - endpoint: address: socket_address: address: 127.0.0.1 port_value: 10003 |
...
The following changes are required if different OAuth2 servers are needed for different projects. All other configurations remain the same.
...
Virtual service to support multiple servers
Code Block | ||||
---|---|---|---|---|
| ||||
apiVersion: networking.istio.io/v1alpha3 kind: VirtualService metadata: name: orchestrator namespace: test spec: hosts: - "*" gateways: - orchestrator-gateway http: - match: - uri: prefix: /v2/oauth - uri: prefix: /v2 - uri: prefix: /v2/projects/enterprise1/oauth -uri: prefix: /v2/projects/enterprise2/oauth route: - destination: port: number: 9015 host: orchestrator |
...
Authentication Policy with multiple servers
Code Block | ||||
---|---|---|---|---|
| ||||
--- apiVersion: "authentication.istio.io/v1alpha1" kind: "Policy" metadata: name: "orchestrator-authn-policy" namespace: istio-system spec: origins: - jwt: issuer: "https://<url>/auth/realms/enterprise1" jwksUri: "http://<url>/auth/realms/enterprise1/protocol/openid-connect/certs" - jwt: issuer: "https://<url>/auth/realms/enterprise2" jwksUri: "http://<url>/auth/realms/enterprise2/protocol/openid-connect/certs" principalBinding: USE_ORIGIN |
...
Configmap for multiple servers.
The following example shows how to setup authservice with multiple OAUTH2 keycloak servers.
...