How to properly setup ZAC and management API

Hi @ivryn, welcome to the community and to OpenZiti! I've put up a short video demonstrating how and all the commands for this demo into this post as well as a gist.

gist url:

commands

1. setup

ziti run quickstart --home /tmp/identity-based-access --ctrl-address localhost --router-address localhost

New terminal:

ziti login localhost:1280 -u admin -p admin -y

ziti create config mgmt-intercept intercept.v1 \
  '{"protocols":["tcp"],"addresses":["mgmt.ziti"],"portRanges":[{"low":1280,"high":1280}]}'
ziti create service mgmt --configs mgmt-intercept
ziti create identity ctrl-mgmt   -a mgmt.binders -o /tmp/identity-based-access/ctrl-mgmt.jwt
ziti create identity mgmt-admin  -a mgmt.dialers -o /tmp/identity-based-access/mgmt-admin.jwt
ziti create identity mgmt-tunnel -a mgmt.dialers -o /tmp/identity-based-access/mgmt-tunnel.jwt
ziti enroll identity /tmp/identity-based-access/ctrl-mgmt.jwt   -o /tmp/identity-based-access/ctrl-mgmt.json
ziti enroll identity /tmp/identity-based-access/mgmt-admin.jwt  -o /tmp/identity-based-access/mgmt-admin.json
ziti enroll identity /tmp/identity-based-access/mgmt-tunnel.jwt -o /tmp/identity-based-access/mgmt-tunnel.json
ziti create service-policy mgmt-bind Bind --identity-roles '#mgmt.binders' --service-roles '@mgmt'
ziti create service-policy mgmt-dial Dial --identity-roles '#mgmt.dialers' --service-roles '@mgmt'

# reuse the quickstart's existing server key, add mgmt.ziti to the SANs
ziti pki create server --pki-root /tmp/identity-based-access/pki \
  --ca-name intermediate-ca-instance-1 \
  --key-file server --server-file mgmt-server \
  --dns localhost,mgmt.ziti --ip 127.0.0.1 --allow-overwrite

2. split the api

Stops the quickstart, truncates the config at web:, appends the new listeners:

pkill -f 'ziti run quickstart'
sleep 3

CFG=/tmp/identity-based-access/instance-1/ctrl.yaml
awk '/^web:/{exit} {print}' "$CFG" > "$CFG.new"
cat >> "$CFG.new" <<'YAML'
web:
  - name: public
    bindPoints:
      - interface: 0.0.0.0:1280
        address: localhost:1280
    identity:
      ca:          "/tmp/identity-based-access/pki/root-ca/certs/root-ca.cert"
      key:         "/tmp/identity-based-access/pki/intermediate-ca-instance-1/keys/server.key"
      server_cert: "/tmp/identity-based-access/pki/intermediate-ca-instance-1/certs/server.chain.pem"
      cert:        "/tmp/identity-based-access/pki/intermediate-ca-instance-1/certs/client.chain.pem"
    options:
      idleTimeout: 5000ms
      readTimeout: 5000ms
      writeTimeout: 100000ms
      minTLSVersion: TLS1.2
      maxTLSVersion: TLS1.3
    apis:
      - binding: edge-client
        options: { }
      - binding: edge-oidc
        options: { }

  - name: private
    bindPoints:
      - interface: 127.0.0.1:1281
        address: localhost:1281
      - identity:
          file: "/tmp/identity-based-access/ctrl-mgmt.json"
          service: "mgmt"
    identity:
      ca:          "/tmp/identity-based-access/pki/root-ca/certs/root-ca.cert"
      key:         "/tmp/identity-based-access/pki/intermediate-ca-instance-1/keys/server.key"
      server_cert: "/tmp/identity-based-access/pki/intermediate-ca-instance-1/certs/mgmt-server.chain.pem"
      cert:        "/tmp/identity-based-access/pki/intermediate-ca-instance-1/certs/client.chain.pem"
    options:
      idleTimeout: 5000ms
      readTimeout: 5000ms
      writeTimeout: 100000ms
      minTLSVersion: TLS1.2
      maxTLSVersion: TLS1.3
    apis:
      - binding: edge-management
        options: { }
      - binding: fabric
        options: { }
      - binding: edge-oidc
        options: { }
YAML
mv "$CFG.new" "$CFG"

edge-oidc is necessary on both listeners — see #4185.

3. restart

ziti run quickstart --home /tmp/identity-based-access --ctrl-address localhost --router-address localhost

Wait for terminator established in the output before step 5. On restart the controller tries to bind
mgmt before raft has elected a leader; that attempt fails with cluster has no leader and the SDK retries
on a 60s timer, so the terminator appears ~65s in. Until then you'll get
service 'mgmt' ... has no terminators.

4. management is gone from the public port

curl -sk -o /dev/null -w '%{http_code}\n' https://localhost:1280/edge/client/v1/version       # 200
curl -sk -o /dev/null -w '%{http_code}\n' https://localhost:1280/edge/management/v1/version   # 404
curl -sk -o /dev/null -w '%{http_code}\n' https://localhost:1281/edge/management/v1/version   # 200

5. reach it over the overlay

Over the overlay:

ziti login localhost:1281 -u admin -p admin -y
ziti list terminators
jq -r .edgeIdentities.default.url ~/.config/ziti/ziti-cli.json

ziti login https://mgmt.ziti:1280 -u admin -p admin \
  --network-identity /tmp/identity-based-access/mgmt-admin.json -y
ziti list terminators
jq -r .edgeIdentities.default.url ~/.config/ziti/ziti-cli.json

6. same from a tunneler

sudo ziti-edge-tunnel run -i /tmp/identity-based-access/mgmt-tunnel.json

New terminal:

curl -s --cacert /tmp/identity-based-access/pki/root-ca/certs/root-ca.cert \
  -o /dev/null -w '%{http_code} %{remote_ip}\n' \
  https://mgmt.ziti:1280/edge/management/v1/version   # 200 100.64.0.3

and

curl -sk https://mgmt.ziti:1280/edge/management/v1/version | jq .

teardown

sudo pkill -f ziti-edge-tunnel
pkill -f 'ziti run quickstart'
rm -rf /tmp/identity-based-access ~/.config/ziti