How consul utilised SPIFFE identifiers during authentication and authorisation

Hi There,

I was wondering how does Consul / Consul intentions use SPIFFE identities to authenticate a service and then authorise access? The intention policies only identify the client service with a name. Can that name be replaces by the client SPIFFE identifier?

Thanks,
S.

Hi @sasanplus ,

Welcome to the HashiCorp Forums!

This section in the official documentation talks about SPIFFE. Service Mesh - How it Works | Consul | HashiCorp Developer

While the intention policy is based on Service Names, it is translated to the SPIFFEE IDs in the certificates generated for Services. The following steps show this in action.

$ nohup consul agent -dev 2>&1 &

$ curl -s localhost:8500/v1/agent/connect/ca/leaf/web | jq .ServiceURI
"spiffe://7ca5b608-f965-17ed-9dfe-85ce5320860e.consul/ns/default/dc/dc1/svc/web"

$ curl -s localhost:8500/v1/agent/connect/ca/leaf/web | jq -r .CertPEM | openssl x509 -text -noout
Certificate:

    ...
            X509v3 Subject Alternative Name: critical
                URI:spiffe://7ca5b608-f965-17ed-9dfe-85ce5320860e.consul/ns/default/dc/dc1/svc/web
    Signature Algorithm: ecdsa-with-SHA256
    ...

These certificates are used by the respective sidecar proxies when connecting to their upstream services. After completing the mTLS handshake, the upstream sidecar proxy will verify the SPIFEE ID to see whether the request should be allowed. You can see this if you dump the configurations of the upstream sidecar proxy (envoy). The following example is from a service named backend and I have explicitly denied the requests from the frontend service using consul intention create -deny frontend backend.

So even though we specify the service name in Consul, they are internally mapped to the SPIFFEE IDs.

       "filter_chains": [
        {
         "filters": [
          {
           "name": "envoy.filters.network.rbac",
           "typed_config": {
            "@type": "type.googleapis.com/envoy.extensions.filters.network.rbac.v3.RBAC",
            "rules": {
             "action": "DENY",
             "policies": {
              "consul-intentions-layer4": {
               "permissions": [
                {
                 "any": true
                }
               ],
               "principals": [
                {
                 "authenticated": {
                  "principal_name": {
                   "safe_regex": {
                    "regex": "^spiffe://d330c3a1-57bf-ac4e-ab40-f3a71c09e68d.consul/ns/default/dc/[^/]+/svc/frontend$"
                   }
                  }
                 }
                }
               ]
              }
             }
            },
            "stat_prefix": "connect_authz"
           }
          }

I hope this makes it clear.

1 Like