Documentation

Enforcer API

About the Enforcer API

Use the RESTful Enforcer API to obtain credentials to access third-party services. It returns the following types of credentials.

You can also use the Enforcer API to check the enforcer’s health and discover the network policies that apply to your application.

Each Aporeto enforcer exposes the API to the processing units on its host. It supports read operations via the GET method. While you can write your applications in any language, the examples that follow use curl.

The application must make its requests from within a processing unit. If it’s running in a container, you’re set. Otherwise, enable host protection.

Accessing the Enforcer API

Processing units can access the Enforcer API over HTTP at the following link-local address: 169.254.254.1. To mitigate server-side request forgery (SSRF) vulnerabilities, all endpoints require X-Aporeto-Metadata: secrets in the HTTP header—except the health endpoint.

Enforcer API endpoints

certificate

Returns a SPIFFE-compliant service certificate as raw data. The certificate contains a SPIFFE ID under subject alternate names in the following syntax: URI:spiffe://<namespace>/<service>. If you have defined a service to represent your application, the value of <service> will be its name. Otherwise, Aporeto uses the ID of the processing unit. Because processing unit IDs are somewhat ephemeral, we recommend defining a service for best results.

An example with an ID follows: URI:spiffe://acme/team-a/5df167fb251c920001edfa6e. This certificate can be used to establish a mutual TLS connection and authenticate to SPIFFE-compliant third parties like Vault.

  • Example request

    curl http://169.254.254.1/certificate -H "X-Aporeto-Metadata: secrets"
    
  • Example response

    -----BEGIN CERTIFICATE-----
    MIICmDCCAj6gAwIBAgIQZ1YI8qAizHAE3ZAzIa4wTTAKBggqhkjOPQQDAjAkMSIw
    IAYDVQQDExlwcmVwcm9kIFB1YmxpYyBTaWduaW5nIENBMB4XDTE5MTIxMTIxMDQ0
    NFoXDTE5MTIxMTIzMDQ0NFowYTEgMB4GA1UEChMXL2Fwb3JldG9kZXYvZW1pbHkv
    bGludXgxGjAYBgNVBAsTEWFwb3JldG8tZW5mb3JjZXJkMSEwHwYDVQQDExg1ZGYx
    gcSGOHNwaWZmZTovL2Fwb3JldG9kZXYvZW1pbHkvbGludXgvNWRmMTY3ZmIyNTFj
    NjdmYjI1MWM5MjAwMDFlZGZhNmUwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASg
    FfGZSvaBitos4lmJvcwAOFe8tPYDBkoymW4NxI6jMn2gMCvgQQe9DfhYeYziQhiN
    xnuQ11ec3tOVUcvw1OR/o4IBEzCCAQ8wDgYDVR0PAQH/BAQDAgWgMB0GA1UdJQQW
    MBQGCCsGAQUFBwMBBggrBgEFBQcDAjAMBgNVHRMBAf8EAjAAMIHPBgNVHREEgccw
    OTIwMDAxZWRmYTZlgglsb2NhbGhvc3SCDWlwNi1sb2NhbGhvc3SCLGlwLTE3Mi0z
    MS0yOC0xMjkudXMtd2VzdC0yLmNvbXB1dGUuaW50ZXJuYWwughBpcC0xNzItMzEt
    MjgtMTI5hwR/AAABhxAAAAAAAAAAAAAAAAAAAAABhwSsHxyBhxD+gAAAAAAAAACM
    6//+U5M6MAoGCCqGSM49BAMCA0gAMEUCIQCqbeVpceUQ8x/ETwGyapa++olobve2
    Vu1DSbcDdZgocgIgSjj3she6zkIQDpbQeVK2v9DtQ5IrDHPeZGGgJdhP2EI=
    -----END CERTIFICATE-----
    

health

No header required.

  • Example request

    curl http://169.254.254.1/health
    
  • Example response

    OK
    

key

Returns the private key of the certificate as raw data.

  • Example request

    curl http://169.254.254.1/key -H "X-Aporeto-Metadata: secrets"
    
  • Example response

    -----BEGIN EC PRIVATE KEY-----
    AwEHoUQDQgAEoBXxmUr2gYraLOJZib3MADhXvLT2AwZKMpluDcSOozJ9oDAr4EEH
    MHcCAQEEICo0A8IVu/IauUNAscjJx93lBS/yp5uePffkzncGjwmZoAoGCCqGSM49
    vQ34WHmM4kIYjcZ7kNdXnN7TlVHL8NTkfw==
    -----END EC PRIVATE KEY-----
    

policy

Returns the policy of the processing unit in JSON format.

  • Example request

    curl http://169.254.254.1/policy -H "X-Aporeto-Metadata: secrets"
    
  • Example response

    {
      "managementID": "5df167fb251c920001edfa6e",
      "managementNamespace": "/acme/team-a",
      "triremeAction": 2,
      "applicationACLs": [
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": [
            "1:65535"
          ],
          "Protocols": [
            "6"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        },
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": [
            "1:65535"
          ],
          "Protocols": [
            "17"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        },
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": null,
          "Protocols": [
            "1"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        }
      ],
      "networkACLs": [
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": [
            "1:65535"
          ],
          "Protocols": [
            "6"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        },
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": [
            "1:65535"
          ],
          "Protocols": [
            "17"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        },
        {
          "Addresses": [
            "0.0.0.0/0"
          ],
          "Ports": null,
          "Protocols": [
            "1"
          ],
          "Extensions": null,
          "Policy": {
            "ObserveAction": 0,
            "Action": 9,
            "ServiceID": "5dd6fded251c920001ed5887",
            "PolicyID": "5df137afa7ba960001a203cb",
            "Labels": [
              "ext:net=internet"
            ]
          }
        }
      ],
      "identity": {
        "Tags": [
          "$identity=processingunit",
          "$namespace=/acme/team-a",
          "AporetoContextID=5df167fb251c920001edfa6e"
        ]
      },
      "annotations": {
        "Tags": [
          "@app:linux:filechecksum=557c0271e30cf474e0f46f93721fd1ba",
          "@app:linux:lib:libtinfo.so.5=true",
          ...
          "$id=5df167fb251c920001edfa6e",
          "$namespace=/acme/team-a"
        ]
      },
      "compressedtags": {
        "Tags": [
          "eJ1s03u72o6i",
          "QuPSyHeRvlcV"
        ]
      },
      "transmitterRules": [
        {
          "Clause": [
            {
              "Key": "$identity",
              "Value": [
                "processingunit"
              ],
              "Operator": "=",
              "ID": "eJ1s03u72o6i"
            }
          ],
          "Policy": {
            "ObserveAction": 0,
            "Action": 1,
            "ServiceID": "",
            "PolicyID": "/aporetodev/emily:5df137afa7ba960001a203cb",
            "Labels": null
          }
        },
        {
          "Clause": [
            {
              "Key": "ext:net",
              "Value": [
                "internet"
              ],
              "Operator": "=",
              "ID": "zlLI4XFOEbpU"
            }
          ],
          "Policy": {
            "ObserveAction": 0,
            "Action": 1,
            "ServiceID": "",
            "PolicyID": "/acme/team-a:5df137afa7ba960001a203cb",
            "Labels": null
          }
        }
      ],
      "receiverRules": [
        {
          "Clause": [
            {
              "Key": "$identity",
              "Value": [
                "processingunit"
              ],
              "Operator": "=",
              "ID": "eJ1s03u72o6i"
            }
          ],
          "Policy": {
            "ObserveAction": 0,
            "Action": 1,
            "ServiceID": "",
            "PolicyID": "/acme/team-a:5df137afa7ba960001a203cb",
            "Labels": null
          }
        },
        {
          "Clause": [
            {
              "Key": "ext:net",
              "Value": [
                "internet"
              ],
              "Operator": "=",
              "ID": "zlLI4XFOEbpU"
            }
          ],
          "Policy": {
            "ObserveAction": 0,
            "Action": 1,
            "ServiceID": "",
            "PolicyID": "/acme/team-a:5df137afa7ba960001a203cb",
            "Labels": null
          }
        }
      ],
      "IPs": {
        "bridge": "0.0.0.0/0"
      },
      "servicesListeningPort": 20992,
      "dnsProxyPort": 20993,
      "dependentServices": [
        {
          "ID": "default",
          "NetworkInfo": {
            "ports": {
              "Min": 80,
              "Max": 80
            },
            "Port": 0,
            "protocol": 6,
            "addresses": [
              {
                "IP": "169.254.254.1",
                "Mask": "/////w=="
              }
            ]
          },
          "PrivateNetworkInfo": {
            "ports": {
              "Min": 80,
              "Max": 80
            },
            "Port": 0,
            "protocol": 6,
            "addresses": [
              {
                "IP": "169.254.254.1",
                "Mask": "/////w=="
              }
            ]
          },
          "PrivateTLSListener": false,
          "NoTLSExternalService": false,
          "PublicNetworkInfo": null,
          "Type": 1,
          "HTTPRules": [
            {
              "URIs": [
                "/certificate"
              ],
              "Methods": [
                "GET"
              ],
              "ClaimMatchingRules": null,
              "Public": true,
              "HookMethod": "metadata:certificate"
            },
            {
              "URIs": [
                "/key"
                ],
              "Methods": [
                "GET"
              ],
              "ClaimMatchingRules": null,
              "Public": true,
              "HookMethod": "metadata:key"
            },
            {
              "URIs": [
                "/health"
              ],
              "Methods": [
                "GET"
              ],
              "ClaimMatchingRules": null,
              "Public": true,
              "HookMethod": "metadata:health"
            },
            {
              "URIs": [
                "/token"
              ],
              "Methods": [
                "GET"
              ],
              "ClaimMatchingRules": null,
              "Public": true,
              "HookMethod": "metadata:token"
            },
            {
              "URIs": [
                "/policy"
              ],
              "Methods": [
                "GET"
              ],
              "ClaimMatchingRules": null,
              "Public": true,
              "HookMethod": "metadata:policy"
            }
          ],
          "Tags": {
            "Tags": []
          },
          "FallbackJWTAuthorizationCert": "",
          "UserAuthorizationType": 0,
          "UserAuthorizationHandler": null,
          "UserTokenToHTTPMappings": null,
          "UserRedirectOnAuthorizationFail": "",
          "External": true,
          "CACert": null,
          "AuthToken": "",
          "MutualTLSTrustedRoots": null,
          "PublicServiceCertificate": null,
          "PublicServiceCertificateKey": null,
          "PublicServiceNoTLS": false
        }
      ]
    }
    

token

The token endpoint returns an Aporeto token that you can pass to AWS in exchange for an AWS security token. It accepts three parameters, all optional.

Parameter Value Description
type AWS or OAUTH Both return an Aporeto token. Defaults to OAUTH.
audience string If the token type is OAUTH, you can use this parameter to pass the audience value. For the AWS token type, leave this blank. You must set the audience in the token scope policy.
validity Golang duration How long the token should remain valid. Defaults to 60 minutes.
  • Example request

    curl http://169.254.254.1/token?type=OAUTH?audience=i-deserve-a-token?validity=24h -H "X-Aporeto-Metadata: secrets"
    
  • Example response

    eyJhbGciOiJSUzI1NiIsImtpZCI6IjVlNGYxODY5YTkwZDBhMDAwMWM0OTBkNyIsInR5cCI6IkpXVCJ9.eyJ1c2VyIjp7IkBhd3Nyb2xlIjoiYXJuOmF3czppYW06OjkyWjA4ODkzMjE0OTpyb2xlL2Fwb3JldG8taWRwIn0sImF1ZCI6ImlfZGVzZXJ2ZV9hX3Rva2VuIiwiZXhwIjoxNTgyMjUxMjIwLCJpYXQiOjE1ODIyNDc2MjAsImlzcyI6Imh0dHBzOi8vYXBpLnByZXByb2QuYXBvcmV0by51cy92LzEvbmFtZXNwYWNlcy81ZTNiMGI0NTBhNzhkMjAwMDFkMjkxMTMvb2F1dGhpbmZvIiwic3ViIjoiNWU0ZjIyZDY4ZTIyMTQwMDAxNzFlODlhIn0.BRG19YvVawW0wVtbycWhxjKLYdhJCcn6WZ4lxFtMalPkj0W5DHdz7Oy1zSskWSQxrK6QgJGIHqsi7W-8fIZ318998RCt6TRuQGkYb6Y4b3gnmWl2I80DJI55h6I-n5ir7upJYi3aZUH_Wz8Gm6ZZiWt65tLY9DorGqEvzRaxIGz-p0Na_-SxxBWw_gO8xoEiSFtUr--uUDRwPT-aXYp8w40qHkmyNrd1z8ihBy31Xfm0USZ7UNnCfNSmHVcU1tqa8rUZMTdU3hDENhsiwS9soZEsFDrR_vGXS0clLqshA2B-KLmBhShodk1Mn-KvXJD78onxsq618Q0uMWKF4iN38A