OpenAPI Spec Mismatch: serviceDetail.config nullability

Hello,
I believe I have found an issue with your OpenAPI Spec.

The config map of a serviceDetail can apparently be null, so i guess x-nullable: true should be added? serviceDetail starts at line 22178 of the Ziti Edge Management (0.26.52) spec:

definitions:
  serviceDetail:
      properties:
        config: <-- This is null
          description: map of config data for this service keyed by the config type
            name. Only configs of the types requested will be returned.
          type: object
          additionalProperties:
            type: object
            additionalProperties:
              type: object

Here is the JSON response when requesting the services for one of my identities:

{
  "data": [
    {
      "_links": {
        "configs": {
          "href": "./services/S87H4YZ9Rr47UcRLTkMd5/configs"
        },
        "self": {
          "href": "./services/S87H4YZ9Rr47UcRLTkMd5"
        },
        "service-edge-router-policies": {
          "href": "./services/S87H4YZ9Rr47UcRLTkMd5/service-edge-router-policies"
        },
        "service-policies": {
          "href": "./services/S87H4YZ9Rr47UcRLTkMd5/service-policies"
        },
        "terminators": {
          "href": "./services/S87H4YZ9Rr47UcRLTkMd5/terminators"
        }
      },
      "createdAt": "2025-12-29T01:35:30.921Z",
      "id": "S87H4YZ9Rr47UcRLTkMd5",
      "tags": {},
      "updatedAt": "2025-12-29T01:35:30.921Z",
      "config": null,
      "configs": [
        "52oxUGZGIfbBzlcAexbrt8",
        "sEjLaDFrE5lCFIG6kUUYg"
      ],
      "encryptionRequired": true,
      "maxIdleTimeMillis": 0,
      "name": "Test",
      "permissions": null,
      "postureQueries": [],
      "roleAttributes": null,
      "terminatorStrategy": "smartrouting"
    }
  ],
  "meta": {
    "filterableFields": [
      "createdAt",
      "updatedAt",
      "isSystem",
      "roleAttributes",
      "configs",
      "id",
      "tags",
      "terminatorStrategy",
      "name"
    ],
    "pagination": {
      "limit": 10,
      "offset": 0,
      "totalCount": 1
    }
  }
}

Thank you for your time and effort.

That's definitely interesting. Can you share exactly how you're listing the services for the identity? Are you using the go sdk or the rest api or something else? If you use the ziti cli does it also report that config as null? ziti edge list services 'id="S87H4YZ9Rr47UcRLTkMd5"' -j?

When I use the ziti CLI to list identities, they are all empty (as in {}, not null). It's just for this one identity?

Thank you for the quick reply.
I am using the REST API, the List accessible services Endpoint (/identities/{id}/services) to be exact. This curl command reproduces the request:

curl -k -X 'GET' \
        'https://my.ziti.controller:1280/edge/management/v1/identities/-F68kNUo8/services' \
        -H 'accept: application/json' \
        -H 'zt-session: long-session-token'

When getting the services via the ziti CLI, I receive an empty set {}, just like you:

#(No need for filters, i got just this service)
admin@zitipi:~ $ ziti edge list services -j
{
    "data": [
        {
            "_links": {
                "configs": {
                    "href": "./services/S87H4YZ9Rr47UcRLTkMd5/configs"
                },
                "self": {
                    "href": "./services/S87H4YZ9Rr47UcRLTkMd5"
                },
                "service-edge-router-policies": {
                    "href": "./services/S87H4YZ9Rr47UcRLTkMd5/service-edge-router-policies"
                },
                "service-policies": {
                    "href": "./services/S87H4YZ9Rr47UcRLTkMd5/service-policies"
                },
                "terminators": {
                    "href": "./services/S87H4YZ9Rr47UcRLTkMd5/terminators"
                }
            },
            "createdAt": "2025-12-29T01:35:30.921Z",
            "id": "S87H4YZ9Rr47UcRLTkMd5",
            "tags": {},
            "updatedAt": "2025-12-29T01:35:30.921Z",
            "config": {},
            "configs": [
                "52oxUGZGIfbBzlcAexbrt8",
                "sEjLaDFrE5lCFIG6kUUYg"
            ],
            "encryptionRequired": true,
            "maxIdleTimeMillis": 0,
            "name": "Test",
            "permissions": [
                "Invalid"
            ],
            "postureQueries": [
                {
                    "isPassing": true,
                    "policyId": "dummy invalid policy: no posture checks defined",
                    "policyType": "Invalid",
                    "postureQueries": []
                }
            ],
            "roleAttributes": null,
            "terminatorStrategy": "smartrouting"
        }
    ],
    "meta": {
        "filterableFields": [
            "tags",
            "isSystem",
            "terminatorStrategy",
            "name",
            "id",
            "createdAt",
            "roleAttributes",
            "configs",
            "updatedAt"
        ],
        "pagination": {
            "limit": 10,
            "offset": 0,
            "totalCount": 1
        }
    }
}

Other identities and services also receive the same null config when requesting via REST:

$ curl -k -X 'GET' \
        'https://ziti.pommer.info:1280/edge/management/v1/identities/HWbhOyGMcL/services' \
        -H 'accept: application/json' \
        -H 'zt-session: 146790c4-9d36-46a4-8bee-f08699da4572'
{
    "data": [
        {
            "_links": {
                "configs": {
                    "href": "./services/Ufnn7DHcfTlZDj7bKUHyc/configs"
                },
                "self": {
                    "href": "./services/Ufnn7DHcfTlZDj7bKUHyc"
                },
                "service-edge-router-policies": {
                    "href": "./services/Ufnn7DHcfTlZDj7bKUHyc/service-edge-router-policies"
                },
                "service-policies": {
                    "href": "./services/Ufnn7DHcfTlZDj7bKUHyc/service-policies"
                },
                "terminators": {
                    "href": "./services/Ufnn7DHcfTlZDj7bKUHyc/terminators"
                }
            },
            "createdAt": "2025-12-29T15:39:40.227Z",
            "id": "Ufnn7DHcfTlZDj7bKUHyc",
            "tags": {},
            "updatedAt": "2025-12-29T15:39:40.227Z",
            "config": null,
            "configs": [
                "7SipV4QUbEgw3lJDSa0MlR",
                "7e5wgrAo65dOkfo9aSELYL"
            ],
            "encryptionRequired": true,
            "maxIdleTimeMillis": 0,
            "name": "Test2",
            "permissions": null,
            "postureQueries": [],
            "roleAttributes": null,
            "terminatorStrategy": "smartrouting"
        }
    ],
    "meta": {
        "filterableFields": [
            "isSystem",
            "terminatorStrategy",
            "name",
            "id",
            "createdAt",
            "roleAttributes",
            "configs",
            "updatedAt",
            "tags"
        ],
        "pagination": {
            "limit": 10,
            "offset": 0,
            "totalCount": 1
        }
    }
}

If there is anything more I can do to diagnose this, feel free to tell me.

Thanks, that information helped me reproduce the issue. I'll file an issue, I'm not sure if the expectation is that the config is empty or if the spec should be updated. It'll obviously be one or the other but I'll have to verify with @andrew.martinez what he wants here and then we (well probably he) will file a bug or just fix the issue.

curl -sk -X 'GET'         'https://localhost:8441/edge/management/v1/identities/82NKXk1qCH/services'         -H 'accept: application/jso
n'         -H 'Authorization: Bearer '$bearer | jq .data[].confg
null
null
null
null

I filed spec or code needs to be updated for /edge/management/v1/identities/${id}/services · Issue #3481 · openziti/ziti · GitHub for this FYI