# Issues regarding Management API over Ziti cli

**URL:** <https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819>\
**Category:** Ziti Overlay\
**Created:** [July 5, 2024, 12:28pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819 "2024-07-05T12:28:33Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 12:28pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/1 "2024-07-05T12:28:34Z")

</div>

Hi , I was trying to bring the things I did with ziti cli (such as creating private routers , services , policies.. etc) via API . In this case its management API

I have deployed the router in postgres host and tried to create identities , services everything via API .

Status of the things done:  
I was able to see the router is online ,  
I was not able to see terminators for services .

Please either point the issue or guide me how to debug it .

Following are the steps I did :

```auto
export ZITI_URL="https://<my_ziti_url>:1280"
export USERNAME="admin"
export password=$(kubectl get secrets "ziti-controller-admin-secret" \
--namespace "ziti" \
--output go-template='{{index .data "admin-password" | base64decode }}')

response=$(curl -s -X POST "$ZITI_URL/edge/management/v1/authenticate?method=password" \
-H "Content-Type: application/json" \
-d "{\"username\": \"$USERNAME\", \"password\": \"$password\"}" --insecure)

# Extract the session token from the response
session=$(echo $response | jq -r '.data.token')

## created router in postgres host 

routerName="router-test6"
roleAttributes=("router-group-test")
isTunnelerEnabled=true # Set this to true

# Create the edge router identity
routerResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/edge-routers" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "'"$routerName"'",
    "roleAttributes": ["'"${roleAttributes[@]}"'"],
    "isTunnelerEnabled": '$isTunnelerEnabled'
  }' --insecure)

# Output the created edge router details
echo "Created Edge Router:"
echo "$routerResponse" | jq

edgeRouterId=$(echo $edgeRouterResponse | jq -r '.data.id')

echo "routerID is $edgeRouterId"

edgeRouterResponse=$(curl -s -X GET "$edgeRouterEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure)

enrollmentJwt=$(echo $edgeRouterResponse | jq -r '.data.enrollmentJwt')  
## used this jwt for running the router and the router is online

# -------------------------

# Example usage of variables in curl commands
# Create Identity
IdentityName=client-6
ClientAttribute=client-group-6

IdentityResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/identities" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "'"$IdentityName"'",
    "isAdmin": false,
    "type": "User",
    "roleAttributes": ["'"$ClientAttribute"'"],
    "enrollment": {
      "type": "OTT"  
    }
  }' --insecure)

# Extract Identity ID
ClientId=$(echo $IdentityResponse | jq -r .data.id)

## jR5BRdjpG

enrollmentsEndpoint="$ZITI_URL/edge/management/v1/enrollments"

# Example enrollment data (adjust as per your requirements)
enrollmentData='{
  "expiresAt": "2024-08-24T14:15:22Z",
  "identityId": "'"$ClientId"'",
  "method": "ott"
}'

# Create enrollment
enrollmentResponse=$(curl -s -X POST "$enrollmentsEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d "$enrollmentData" \
  --insecure)

# Extract the enrollment ID from the response
enrollmentId=$(echo $enrollmentResponse | jq -r '.data.id')

# Retrieve enrollment details to get the JWT token
enrollmentDetailsEndpoint="$enrollmentsEndpoint/$enrollmentId"
enrollmentDetailsResponse=$(curl -s -X GET "$enrollmentDetailsEndpoint" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure)

# Extract the JWT token from enrollmentDetailsResponse using jq
jwtToken=$(echo $enrollmentDetailsResponse | jq -r '.data.jwt')

# Output the JWT token
echo "JWT Token: $jwtToken"

curl -s -X GET "$ZITI_URL/edge/management/v1/config-types" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  --insecure | jq '.data[] | select(.name == "host.v1")'

# Create Intercept Config
interceptConfigResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/configs" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-intercept",
    "configTypeId": "g7cIWbcGg",
    "data": {
      "protocols": ["tcp"],
      "addresses": ["post.ziti.internal"],
      "portRanges": [{"low": 5432, "high": 5432}]
    }
  }' --insecure)

interceptConfigId=$(echo $interceptConfigResponse | jq -r '.data.id')

echo "Intercept Config is $interceptConfigId"

## Intercept Config is R15ZcOGsxKWvVgiy0EwCL

# Create Host Config
hostConfigResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/configs" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-host",
    "configTypeId": "NH5p4FpGR",
    "data": {
      "protocol": "tcp",
      "address": "localhost",
      "port": 5432
    }
  }' --insecure)

hostConfigId=$(echo $hostConfigResponse | jq -r '.data.id')

echo "host Config is $hostConfigId"

# host Config is 2Ad5hcUg1Nfd8G1ESKW8tM

# Create Service
serviceResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/services" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6",
    "configs": ["R15ZcOGsxKWvVgiy0EwCL", "2Ad5hcUg1Nfd8G1ESKW8tM"],
    "encryptionRequired": true
  }' --insecure)

serviceId=$(echo $serviceResponse | jq -r '.data.id')
# 1Oh311d9m0gm2vUET6cjya

# Create Dial Policy
createDialPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-dial-policy",
    "type": "Dial",
    "semantic": "AllOf",
    "serviceRoles": ["#all"],
    "identityRoles": ["#client-group-6"]
  }' --insecure)

echo "$createDialPolicyResponse" | jq 

# 39ZQKEsWgoDKVzCDHZP66E

# Create Bind Policy
createBindPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["#all"],
    "identityRoles": ["#router-group-test"]
  }' --insecure)

echo "$createBindPolicyResponse" | jq 

# 45dOY2KZQFMOMF1uxcuJ97

# Retrieve terminators associated with the service ID
terminatorsResponse=$(curl -s -X GET "$ZITI_URL/edge/management/v1/services/1Oh311d9m0gm2vUET6cjya/terminators" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" --insecure)

# Output the terminators
echo "$terminatorsResponse" | jq .data
# [] 

```

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 12:45pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/2 "2024-07-05T12:45:39Z")

</div>

Making GET request to

```auto
$ZITI_URL/edge/management/v1/identities/jR5BRdjpG/policy-advice/1Oh311d9m0gm2vUET6cjya I get

```

```auto

{
    "data": {
      "commonRouters": [
        {
          "_links": {
            "edge-router-policies": {
              "href": "./edge-routers/y6PWYnjpG/edge-router-policies"
            },
            "self": {
              "href": "./edge-routers/y6PWYnjpG"
            }
          },
          "entity": "edge-routers",
          "id": "y6PWYnjpG",
          "name": "router-test6",
          "isOnline": true
        }
      ],
      "identity": {
        "_links": {
          "auth-policies": {
            "href": "./auth-policies/default"
          },
          "authenticators": {
            "href": "./identities/jR5BRdjpG/authenticators"
          },
          "edge-router-policies": {
            "href": "./identities/jR5BRdjpG/edge-router-policies"
          },
          "edge-routers": {
            "href": "./identities/jR5BRdjpG/edge-routers"
          },
          "enrollments": {
            "href": "./identities/jR5BRdjpG/enrollments"
          },
          "failed-service-requests": {
            "href": "./identities/jR5BRdjpG/failed-service-requests"
          },
          "posture-data": {
            "href": "./identities/jR5BRdjpG/posture-data"
          },
          "self": {
            "href": "./identities/jR5BRdjpG"
          },
          "service-configs": {
            "href": "./identities/jR5BRdjpG/service-configs"
          },
          "service-policies": {
            "href": "./identities/jR5BRdjpG/service-policies"
          },
          "services": {
            "href": "./identities/jR5BRdjpG/services"
          }
        },
        "entity": "identities",
        "id": "jR5BRdjpG",
        "name": "client-6"
      },
      "identityId": "jR5BRdjpG",
      "identityRouterCount": 9,
      "isDialAllowed": true,
      "service": {
        "_links": {
          "configs": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/configs"
          },
          "self": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya"
          },
          "service-edge-router-policies": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/service-edge-router-policies"
          },
          "service-policies": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/service-policies"
          },
          "terminators": {
            "href": "./services/1Oh311d9m0gm2vUET6cjya/terminators"
          }
        },
        "entity": "services",
        "id": "1Oh311d9m0gm2vUET6cjya",
        "name": "service-6"
      },
      "serviceId": "1Oh311d9m0gm2vUET6cjya",
      "serviceRouterCount": 9
    },
    "meta": null
  }

```

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 3:02pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/3 "2024-07-05T15:02:57Z")

</div>

works if I do bind-polcy part from ziti cli

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 3:35pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/4 "2024-07-05T15:35:59Z")

</div>

```auto
createBindPolicyResponse=$(curl -s -X POST "$ZITI_URL/edge/management/v1/service-policies" \
  -H "Content-Type: application/json" \
  -H "Zt-Session: $session" \
  -d '{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["@service-6"],
    "identityRoles": ["#router-group"]
  }' --insecure)

echo "$createBindPolicyResponse" | jq 
{
  "error": {
    "cause": {
      "field": "serviceRoles",
      "reason": "no services found with the given ids",
      "value": "[service-6]"
    },
    "code": "COULD_NOT_VALIDATE",
    "message": "The supplied request contains an invalid document or no valid accept content were available, see cause",
    "requestId": "02rKr-jpG"
  },
  "meta": {
    "apiEnrollmentVersion": "0.0.1",
    "apiVersion": "0.0.1"
  }
}

```

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [July 5, 2024, 5:38pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/5 "2024-07-05T17:38:06Z")

</div>

I think the issue you're facing is that there were no terminators listed in the API after you created a service, but it started working correctly?

Then, you tried to create a Bind Service Policy with an explicit mention of a service's symbolic name `@service-6`, and got an error. This is because the API expects the ID, not the symbolic name property of the entity when explicitly granting in a policy, e.g., `@1Oh311d9m0gm2vUET6cjya`.

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 8:14pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/6 "2024-07-05T20:14:53Z")

</div>

ya as the error message suggested , I tried but it does not work . Whereas doing it in old way via cli works

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 5, 2024, 8:17pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/7 "2024-07-05T20:17:40Z")

</div>

If I delete that policy created by api and then just manually you this sort of command

```auto
ziti edge create service-policy "hello-bind-policy" Bind \
    --service-roles '@hello-service' --identity-roles '#hello-hosts'

```

everything works . API issue

---

<div class="post-metadata">

**Author:** ![qrkourier](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/qrkourier/32/52_2.png) [@qrkourier](https://openziti.discourse.group/u/qrkourier)\
**Post date:** [July 5, 2024, 11:57pm UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/8 "2024-07-05T23:57:38Z")

</div>

You may use the unique ID or symbolic name with the CLI. When using the API you must use the unique ID, not the symbolic name.

This is how I think it works, but I wasn't able to test it today:

```json
{
    "name": "service-6-bind-policy",
    "type": "Bind",
    "semantic": "AllOf",
    "serviceRoles": ["@1Oh311d9m0gm2vUET6cjya"],
    "identityRoles": ["#router-group"]
  }

```

---

<div class="post-metadata">

**Author:** ![sadath-12](https://yyz2.discourse-cdn.com/free1/user_avatar/openziti.discourse.group/sadath-12/32/2043_2.png) [@sadath-12](https://openziti.discourse.group/u/sadath-12)\
**Post date:** [July 6, 2024, 5:11am UTC](https://openziti.discourse.group/t/issues-regarding-management-api-over-ziti-cli/2819/9 "2024-07-06T05:11:53Z")

</div>

> [@qrkourier](#):
>
> ```auto
> "name": "service-6-bind-policy",
> "type": "Bind",
> "semantic": "AllOf",
> "serviceRoles": ["@1Oh311d9m0gm2vUET6cjya"],
> "identityRoles": ["#router-group"]
> 
> ```

Ohk Idk how but it works now . thanks alot . maybe the above apis were helpful docs
