Issue in service policy creation?

Hi Team,

While using cli command:
ziti edge create service-policy Test Bind --semantic AnyOf --service-roles @2612
works fine:
New service policy Test created with id: yMuEo1S3JzmLjjzvjEy0s

using API: /edge/management/v1/service-policies with content
{
"name": "Test","semantic": "AnyOf","serviceRoles": ["@2612"],"type": "Bind"
}

gives following error:
"error":
{
"cause":
{
"field":"serviceRoles",
"reason":"role entries must prefixed with # (to indicate role attributes) or @ (to indicate a name or id)",
"value":"[2612]"
},
"code":"COULD_NOT_VALIDATE",
"message":"The supplied request contains an invalid document or no valid accept content were available, see cause",
"requestId":"oDgwAqNTw"
},
"meta":
{
"apiEnrollmentVersion":"0.0.1",
"apiVersion":"0.0.1"
}
}

I tried multiple syntaxes but failed each time. Of course, I'm logged as administrator and other requests like creating identities work fine.

1 Like

It'll be helpful if you could use code fencing when submitting terminal stuff.

Could you try using literal quoting around your parameters? A literal quote will use single quotes

ziti edge... --param 'value '

Like that. See if that matters? I dunno if I've ever tried an identity that was only numbers, i wonder if that's somehow a problem.

I have put single quotes and use alphatic service name but the result remains identical.

{
"error":
{
"cause":
{
"field":"serviceRoles",
"reason":"no services found with the given ids",
"value":"[HFSQL]"
},
"code":"COULD_NOT_VALIDATE",
"message":"The supplied request contains an invalid document or no valid accept content were available, see cause",
"requestId":"FA0vgRNTw"
},
"meta":
{
"apiEnrollmentVersion":"0.0.1",
"apiVersion":"0.0.1"
}
}

This is a different (and very clear) error than the one you first showed.

Can you please show all the command you have used and please use code blocks and code fencing for code, ziti cli commands and json output so that it formats as code. If you use the rich-text editor itโ€™s this button

then your json or ziti CLI commands look like this

It looks to me like you are just referencing a service that doesnโ€™t exist

Using the CLI:

ziti edge create service-policy Test Bind --semantic AnyOf --service-roles @2612
New service policy Test created with id: 68ufJI17N2G6OeGbXnISLe

Now using Postman POST command:

https://zpix.vigitronic.eu:8440/edge/management/v1/service-policies

with following json

{
	"name": "Test",
    "semantic": "AnyOf",
    "serviceRoles": ["@2612"],
    "type": "Bind"
}

Result:

{
    "error": {
        "cause": {
            "field": "serviceRoles",
            "reason": "no services found with the given ids",
            "value": "[2612]"
        },
        "code": "COULD_NOT_VALIDATE",
        "message": "The supplied request contains an invalid document or no valid accept content were available, see cause",
        "requestId": "ShCqmD4sY"
    },
    "meta": {
        "apiEnrollmentVersion": "0.0.1",
        "apiVersion": "0.0.1"
    }
}

Current services:

eric@zpix:~$ ziti edge list services
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                     โ”‚ NAME  โ”‚ ENCRYPTION โ”‚ TERMINATOR STRATEGY โ”‚ ATTRIBUTES โ”‚
โ”‚                        โ”‚       โ”‚ REQUIRED   โ”‚                     โ”‚            โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 1cXQqC5s6i4VFzW67tKmvo โ”‚ RDP   โ”‚ true       โ”‚ smartrouting        โ”‚            โ”‚
โ”‚ 5CgaYBy0a3OL4cHkq9prVu โ”‚ http  โ”‚ true       โ”‚ smartrouting        โ”‚            โ”‚
โ”‚ 6vud897IStOAIB6aa2t1rd โ”‚ HFSQL โ”‚ true       โ”‚ smartrouting        โ”‚            โ”‚
โ”‚ 6yT6ZZqkrBKv9TluLZkOCQ โ”‚ 2612  โ”‚ true       โ”‚ smartrouting        โ”‚            โ”‚
โ”‚ AqErEuQI8ZfkKZzPTaVvt  โ”‚ 2609  โ”‚ true       โ”‚ smartrouting        โ”‚            โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
results: 1-5 of 5

i have tried with all of them, nothing is accepted:

POST https://zpix.vigitronic.eu:8440/edge/management/v1/service-policies

with json:

{
	"name": "Test02",
    "semantic": "AnyOf",
    "serviceRoles": ["@http"],
    "type": "Dial"
}

Result:

{
    "error": {
        "cause": {
            "field": "serviceRoles",
            "reason": "no services found with the given ids",
            "value": "[http]"
        },
        "code": "COULD_NOT_VALIDATE",
        "message": "The supplied request contains an invalid document or no valid accept content were available, see cause",
        "requestId": "ZOI9qFz-0"
    },
    "meta": {
        "apiEnrollmentVersion": "0.0.1",
        "apiVersion": "0.0.1"
    }
}

It's so strange. Other commands like authentication or identity creation work so it's not a communication issue with the controller. Any idea?

Itโ€™s still not clear what youโ€™re attempting to do here. My testing shows that making a service-policy where the referenced service is only numbers works fine. For example:

cdaws:ubuntu@ip-172-31-47-200:~$ ziti edge create service 2612
New service 2612 created with id: 6VYkoEq28pzi4eIhWAhbOd

cdaws:ubuntu@ip-172-31-47-200:~$ ziti edge create service-policy Test Bind --semantic AnyOf --service-roles @2612
New service policy Test created with id: 23ui63RvRuLLpqh4gH0v4b

as you can see, it worked fine:

ziti edge list service-policies 'name contains "Test"'
โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ
โ”‚ ID                     โ”‚ NAME โ”‚ SEMANTIC โ”‚ SERVICE ROLES โ”‚ IDENTITY ROLES โ”‚ POSTURE CHECK ROLES โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ 23ui63RvRuLLpqh4gH0v4b โ”‚ Test โ”‚ AnyOf    โ”‚ @2612         โ”‚                โ”‚                     โ”‚
โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ
results: 1-1 of 1

I think it would help if you can stat what it is youโ€™re trying to accomplish, my hunch here is that youโ€™re just getting confused with the โ€˜@โ€™ and โ€˜#โ€™ syntaxes possibly?

Itโ€™s also exceptionally helpful to me to see the exact ziti CLI commands (as you showed in your previous post)

I see from your post you have a service named โ€˜httpโ€™. Using the ziti cli that works fine too:

cdaws:ubuntu@ip-172-31-47-200:~$ ziti edge create service http
New service http created with id: 6SSIRumO5SPVSaTyiVX9zP

cdaws:ubuntu@ip-172-31-47-200:~$ ziti edge create service-policy HttpDial Dial --semantic AnyOf --service-roles @http
New service policy HttpDial created with id: 1evZpTotPVBeIAD6oW5EaI

I donโ€™t know what the issue is based on the information provided

I don't understand what you mean. I just want to create a service policy using the API. I believe I know the difference between @ and #.

Why does it work in the CLI and fail through the API? I'm stuck with this problem since Saturday. Do you see something wrong in the command or the json? I don't think so.

Do you see something wrong in the command or the json?

Yes, youโ€™re passing the name of the service, not the id of the service. The ziti CLI uses the API. You can see the requests when you use the ziti cli by passing โ€“verbose and โ€“output-request-json.

ziti edge create service-policy HttpDial Dial --semantic AnyOf --service-roles @http --verbose --output-request-json

RESTY 2025/09/01 17:08:22
---------------------- REQUEST LOG -----------------------
GET  /edge/management/v1/services?filter=id%3D%22http%22  HTTP/1.1
HOST   : ziti.controller
HEADERS:
                   Accept: application/json
             Content-Type: application/json
               User-Agent: go-resty/1.12.0 (https://github.com/go-resty/resty)
               Zt-Session: xxxx
BODY   :
***** NO CONTENT *****
----------------------------------------------------------
RESTY 2025/09/01 17:08:22
---------------------- RESPONSE LOG -----------------------
STATUS          : 200 OK
RECEIVED AT     : 2025-09-01T17:08:22.043475221Z
RESPONSE TIME   : 25.722531ms
HEADERS:
             Content-Type: application/json
                     Date: Mon, 01 Sep 2025 17:08:22 GMT
       Expiration-Seconds: 1800
               Expires-At: 2025-09-01 17:38:01.802945256 +0000 UTC
                   Server: ziti-controller/v0.0.0
         Ziti-Instance-Id: cmelwayjw00001lqk1gbclrrc
BODY   :
{
   "data": [],
   "meta": {
      "filterableFields": [
         "id",
         "configs",
         "createdAt",
         "isSystem",
         "terminatorStrategy",
         "tags",
         "roleAttributes",
         "updatedAt",
         "name"
      ],
      "pagination": {
         "limit": 10,
         "offset": 0,
         "totalCount": 0
      }
   }
}

----------------------------------------------------------
RESTY 2025/09/01 17:08:22
---------------------- REQUEST LOG -----------------------
GET  /edge/management/v1/services?filter=name%3D%22http%22  HTTP/1.1
HOST   : ziti.controller
HEADERS:
                   Accept: application/json
             Content-Type: application/json
               User-Agent: go-resty/1.12.0 (https://github.com/go-resty/resty)
               Zt-Session: xxxx
BODY   :
***** NO CONTENT *****
----------------------------------------------------------
RESTY 2025/09/01 17:08:22
---------------------- RESPONSE LOG -----------------------
STATUS          : 200 OK
RECEIVED AT     : 2025-09-01T17:08:22.068564177Z
RESPONSE TIME   : 24.260135ms
HEADERS:
             Content-Type: application/json
                     Date: Mon, 01 Sep 2025 17:08:22 GMT
       Expiration-Seconds: 1800
               Expires-At: 2025-09-01 17:38:01.802945256 +0000 UTC
                   Server: ziti-controller/v0.0.0
         Ziti-Instance-Id: cmelwayjw00001lqk1gbclrrc
BODY   :
{
   "data": [
      {
         "_links": {
            "configs": {
               "href": "./services/68Piq9Q7n1yChH7naG1QtK/configs"
            },
            "self": {
               "href": "./services/68Piq9Q7n1yChH7naG1QtK"
            },
            "service-edge-router-policies": {
               "href": "./services/68Piq9Q7n1yChH7naG1QtK/service-edge-router-policies"
            },
            "service-policies": {
               "href": "./services/68Piq9Q7n1yChH7naG1QtK/service-policies"
            },
            "terminators": {
               "href": "./services/68Piq9Q7n1yChH7naG1QtK/terminators"
            }
         },
         "createdAt": "2025-09-01T17:08:01.048Z",
         "id": "68Piq9Q7n1yChH7naG1QtK",
         "tags": {},
         "updatedAt": "2025-09-01T17:08:01.048Z",
         "config": {},
         "configs": null,
         "encryptionRequired": true,
         "maxIdleTimeMillis": 0,
         "name": "http",
         "permissions": [
            "Invalid"
         ],
         "postureQueries": [
            {
               "isPassing": true,
               "policyId": "dummy invalid policy: no posture checks defined",
               "policyType": "Invalid",
               "postureQueries": []
            }
         ],
         "roleAttributes": null,
         "terminatorStrategy": "smartrouting"
      }
   ],
   "meta": {
      "filterableFields": [
         "createdAt",
         "isSystem",
         "terminatorStrategy",
         "tags",
         "roleAttributes",
         "updatedAt",
         "name",
         "id",
         "configs"
      ],
      "pagination": {
         "limit": 10,
         "offset": 0,
         "totalCount": 1
      }
   }
}

----------------------------------------------------------
POST to https://ziti.controller/edge/management/v1/service-policies
{
    "identityRoles": [],
    "name": "HttpDial",
    "postureCheckRoles": [],
    "semantic": "AnyOf",
    "serviceRoles": [
        "@68Piq9Q7n1yChH7naG1QtK"
    ],
    "tags": {},
    "type": "Dial"
}
RESTY 2025/09/01 17:08:22
---------------------- REQUEST LOG -----------------------
POST  /edge/management/v1/service-policies  HTTP/1.1
HOST   : ziti.controller
HEADERS:
                   Accept: application/json
             Content-Type: application/json
               User-Agent: go-resty/1.12.0 (https://github.com/go-resty/resty)
               Zt-Session: xxxx
BODY   :
{
   "identityRoles": [],
   "name": "HttpDial",
   "postureCheckRoles": [],
   "semantic": "AnyOf",
   "serviceRoles": [
      "@68Piq9Q7n1yChH7naG1QtK"
   ],
   "tags": {},
   "type": "Dial"
}
----------------------------------------------------------
RESTY 2025/09/01 17:08:22
---------------------- RESPONSE LOG -----------------------
STATUS          : 201 Created
RECEIVED AT     : 2025-09-01T17:08:22.098120414Z
RESPONSE TIME   : 28.430354ms
HEADERS:
             Content-Type: application/json
                     Date: Mon, 01 Sep 2025 17:08:22 GMT
       Expiration-Seconds: 1800
               Expires-At: 2025-09-01 17:38:01.802945256 +0000 UTC
                   Server: ziti-controller/v0.0.0
         Ziti-Instance-Id: cmelwayjw00001lqk1gbclrrc
BODY   :
{
   "data": {
      "_links": {
         "self": {
            "href": "./service-policies/4dcT3y1ObxCRYYJBdz89bk"
         }
      },
      "id": "4dcT3y1ObxCRYYJBdz89bk"
   },
   "meta": {}
}

----------------------------------------------------------
New service policy HttpDial created with id: 4dcT3y1ObxCRYYJBdz89bk
cdaws:ubuntu@ip-172-31-47-200:~$

Wow, what a trap! I thought the API was working exactly like the CLI. In addition, in the API documentation and the JSON description, it is written "name", not "id".

I understand that from now on, I'll have to test every CLI command with โ€“verbose and โ€“output-request-json flags to understand what's behind...

Looks like the API needs the service ID (with @) instead of the name. Thatโ€™s why CLI works but Postman fails try using the ID and it should fix the error.

Yes, I agree and confirm. I suggest to change the API description and replace "name" by "id".