* Add CLI and release notes for cross policy entity lists
44 KiB
Release 0.13
Theme
Ziti 0.13 includes the following:
- Changes to make working with policies easier, including
- New APIs to list existing role attributes used by edge routers, identities and services
- New APIs to list entities related by polices (such as listing edge routers available to a service via service edge router policies)
Making Policies More User Friendly
Listing Role Attributes in Use
There are three new endpoints for listing role attributes in use.
* Endpoint: /edge-router-role-attributes
* Endpoint: /identity-role-attributes
* Endpoint: /service-role-attributes
All three support the same operations:
* Supported operations
* List: GET
* Supports filtering
* role attributes can be filtered/sorted using the symbol `id`
* Ex:`?filter=id contains "north" limit 5`
The CLI supports these new operations as well.
ziti edge controller list edge-router-role-attributes
ziti edge controller list identity-role-attributes
ziti edge controller list service-role-attributes
Example output:
$ ec list service-role-attributes "true sort by id desc limit 5" -j
{
"meta": {
"filterableFields": [
"id"
],
"pagination": {
"limit": 5,
"offset": 0,
"totalCount": 10
}
},
"data": [
"two",
"three",
"support",
"sales",
"one"
]
}
Listing Entities Related by Policies
This adds operations to the /services, /identities and /edge-routers endpoints.
* Endpoint: /edge-routers
* New operations
* Query related identities: GET /edge-routers/<edge-router-id>/identities?filter=<optional-filter>
* Query related services: GET /edge-routers/<edge-router-id>/services?filter=<optional-filter>
* Endpoint: /identities
* New operations
* Query related edge routers: GET /identities/<identity-id>/edge-routers?filter=<optional-filter>
* Query related services: GET /identities/<identity-id>/services?filter=<optional-filter>
* Endpoint: /services
* New operations
* Query related identities: GET /services/<service-id>/identities?filter=<optional-filter>
* Query related edge routers: GET /services/<service-id>/edge-routers?filter=<optional-filter>
Release 0.12
Theme
Ziti 0.12 includes the following:
- Terminators have been extracted from services
- Terminators define where a service terminates. Previously each service had exactly one terminator. Now services can have 0 to N terminators.
- List APIs now support inline paging
- Association APIs now support filtering, paging and querying
- The bolt datastore creates a backup of the datastore file before attempting a schema/data migration
- Fabric and edge code are now much more closely aligned at the persistence and model layers
- Some deprecated endpoints are now being removed
Terminators
See https://github.com/netfoundry/ziti-fabric/wiki/Pluggable-Service-Terminators for a discussion of what serivice terminators are, the motivation for extracting them from services and the design for how they will work.
This release includes the following:
- Terminators extracted from service as separate entities
- When SDK applications bind and unbind, the controller now dynamically adds/removes terminators as appropriate
This release does not yet include a terminator strategy API. Strategies can be specified per service, but if a service has multiple terminators the first one will be used. The terminator strategy API along with some implementations will be added in a follow-up release. This release also does not include strategy inputs on terminators as discussed in the above design document. If strategy inputs end up being useful, they may be added in the furure.
Terminator related API changes
There is a new terminators endpoint:
* Endpoint: /terminators
* Supported operations
* Detail: GET /terminators/<terminator-id>
* List: GET /terminators/
* Create: POST /terminators
* Update All Fields: PUT /terminators/<terminator-id>
* Update Selective Fields: PATCH /terminators/<terminator-id>
* Delete: DELETE /terminators/<terminator-id>
* Properties
* Terminators support the standard properties (id, createdAt, updatedAt, tags)
* service - type: uuid, must be a valid service id
* router - type: uuid, must be a valid router id
* binding - type: string. Optional, defaults to "transport". The xgress binding on the selected router to use
* address - type: string. The address that will be dialed using the xgress component on the selected router
The service endpoint has changes as well:
* Endpoint: /services
* New operations
* Query related endpoints: GET /services/<service-id>/terminators?filter=<optional-filter>
* The following properties have been removed
* egressRouter
* endpointAddress
* The following property has been added
* terminatorStrategy - type: string, optional. The terminator strategy to use. Currently unused.
The fabric service definition has also changed (visible from ziti-fabric).
- The following properties have been removed
bindingegressRouterendpointAddress
- The following property has been added
terminatorStrategy
The ziti and ziti-fabric CLIs have been updated with new terminator related functionality, so that terminators can be viewed, created and deleted from both.
Filtering/Sorting/Paging Changes
List operations on entities previously allowed the following parameters:
filtersortlimitoffset
These are all still supported, but now sort, limit and offset can also be included in the filter. If parameters are specified both in the filter and in an explicit query parameter, the filter takes precedence.
When listing entities from the ziti CLI, filters can be included as an optional argument.
For example:
$ ziti edge controller list services
id: 37f1e34c-af06-442f-8e62-032916912bc6 name: grpc-ping-standalone terminator strategy: role attributes: {}
id: 4e33859b-070d-42b1-8b40-4adf973f680c name: simple terminator strategy: role attributes: {}
id: 9480e39d-0664-4482-b230-5da2c17b225b name: iperf terminator strategy: role attributes: {}
id: cd1ae16e-5015-49ad-9864-3ca0f5814091 name: ssh terminator strategy: role attributes: {}
id: dc0446f0-7eaa-465f-80b5-c88f0a6b59cc name: grpc-ping terminator strategy: role attributes: ["fortio","fortio-server"]
id: dcc9922a-c681-41bf-8079-be2163509702 name: mattermost terminator strategy: role attributes: {}
$ ziti edge controller list services 'name contains "s"'
id: 37f1e34c-af06-442f-8e62-032916912bc6 name: grpc-ping-standalone terminator strategy: role attributes: {}
id: 4e33859b-070d-42b1-8b40-4adf973f680c name: simple terminator strategy: role attributes: {}
id: cd1ae16e-5015-49ad-9864-3ca0f5814091 name: ssh terminator strategy: role attributes: {}
id: dcc9922a-c681-41bf-8079-be2163509702 name: mattermost terminator strategy: role attributes: {}
$ ziti edge controller list services 'name contains "s" sort by name'
id: 37f1e34c-af06-442f-8e62-032916912bc6 name: grpc-ping-standalone terminator strategy: role attributes: {}
id: dcc9922a-c681-41bf-8079-be2163509702 name: mattermost terminator strategy: role attributes: {}
id: 4e33859b-070d-42b1-8b40-4adf973f680c name: simple terminator strategy: role attributes: {}
id: cd1ae16e-5015-49ad-9864-3ca0f5814091 name: ssh terminator strategy: role attributes: {}
$ ziti edge controller list services 'name contains "s" sort by name skip 1 limit 2'
id: dcc9922a-c681-41bf-8079-be2163509702 name: mattermost terminator strategy: role attributes: {}
id: 4e33859b-070d-42b1-8b40-4adf973f680c name: simple terminator strategy: role attributes: {}
Association lists now also support filtering, sorting and paging. Association GET operations only support the filter parameter.
$ ziti edge controller list service terminators ssh
Found services with id cd1ae16e-5015-49ad-9864-3ca0f5814091 for name ssh
id: 41f4fd01-0bd7-4987-93b3-3b2217b00a22 serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:22
id: a5213300-9c5f-4b0e-a790-1ed460964d7c serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:2022
$ ziti edge controller list service terminators ssh "true sort by address"
Found services with id cd1ae16e-5015-49ad-9864-3ca0f5814091 for name ssh
id: a5213300-9c5f-4b0e-a790-1ed460964d7c serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:2022
id: 41f4fd01-0bd7-4987-93b3-3b2217b00a22 serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:22
$ ziti edge controller list service terminators ssh "true sort by address desc"
Found services with id cd1ae16e-5015-49ad-9864-3ca0f5814091 for name ssh
id: 41f4fd01-0bd7-4987-93b3-3b2217b00a22 serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:22
id: a5213300-9c5f-4b0e-a790-1ed460964d7c serviceId: cd1ae16e-5015-49ad-9864-3ca0f5814091 routerId: 888cfde1-5786-4ba8-aa75-9f97804cb7bb binding: transport address: tcp:localhost:2022
Bolt Datastore Migrations
The fabric now supports migrating schema/data from one version to another. The fabric and edge share a common framework for migration. The migration framework now also automatically backs up the bolt data file before migration data. The backup file will have the same name as the original bolt file but with a timestamp appended to it.
Example:
Original file: /tmp/ziti-bolt.db
Backup file: /tmp/ziti-bolt.db-20200316-134725
The fabric and edge schemas do not yet get migrated in the same transaction. This will be addressed in a follow-up release.
Fabric and Edge Alignment
The fabric and edge persistence and model layers are now using the same foundational plumbing. This will allow for a common API layer in a follow-up release.
As part of this consolidation effort, fabric entities now share the same set of common properties as edge entities, namely:
idcreatedAtupdatedAttags
Previously the only common property was id.
Deprecated Endpoints
The /gateways (replaced by /edge-routers) and network-sessions (replaced by /sessions) endpoints, which were previously deprecated, have now been removed.
Miscellaneous
There is a new ziti edge controller version command which shows information about the version of the controller being connected to:
Example:
$ ziti edge controller version
Version : v0.9.0
GIT revision: ea556fc18740
Build Date : 2020-02-11 16:09:08
Runtime : go1.13
Release 0.11
##Theme Ziti 0.11 includes the following:
- Ziti connections from Ziti SDK client to services hosted by SDK are encrypted end-to-end (no API changes)
End-to-end Encryption
Client and Hosting SDK instances setup end-to-end channels using secure key exchange and AEAD streams. Read more about on https://netfoundry.github.io/ziti-doc (coming soon)
Releaes 0.10
Theme
Ziti 0.10 includes a single change:
- Edge API input validation processing was changed to operate on the supplied JSON instead of target objects
Edge API Validation
Before this version, the Edge API allowed some fields to be omitted from requests. This behavior was due to the fact that the API was validating the object that resulted from the JSON. This would cause some fields that were not supplied to default to an acceptable nil/null/empty value.
Some APIs call may now fail with validation errors expecting fields to be defined for POST (create) and PUT (update) operations. PATCH (partial update) should not be affected.
Release 0.9
Theme
Ziti 0.9 includes the following
- a generic service configuration facility, useful for configuring service centric edge configuration data
- several changes to policy syntax and semantics
- service edge router policies are now a separate entity, instead of just a field on service
Service Configuration
Configurations are named JSON style objects that can be associated with services. Configurations have a type. A service can have 0 or 1 configurations of each configuration type associated with it.
Configuration types
There is a new endpoint for managing config types.
* Endpoint: `/config-types`
* Supported operations
* Detail: GET `/config-types/<config-type-id>`
* List: GET `/config-types/`
* Create: POST `/config-types`
* Update All Fields: PUT `/config-types/<config-type-id>`
* Update Selective Fields: PATCH `/config-types/<config-type-id>`
* Delete: DELETE `/config-types/<config-type-id>`
* List associated configs GET `/config-types/<config-id>/configs`
* Properties
* Config types support the standard properties (id, createdAt, updatedAt, tags)
* name - type: string, constraints: required, must be unique. If provided must be a valid JSON schema.
* schema - type: object. Optional.
If a schema is set on a type, that schema will be used to validate config data on configurations of that type. Validation will happen if a configuration is created or updated. If a config type schema changes, the system does not re-validate configurations of that type.
It is generally assumed that if there are backwards incompatible changes being made to a schema that a new config type will be created and interested applications can support multiple configuration types.
The ziti CLI supports the following operations on config types:
* create config-type
* list config-types
* list config-type configs
* delete config-type
Configurations
There is a new endpoint for managing configurations
* Endpoint: `/configs`
* Supported operations
* Detail: GET `/configs/<config-id>`
* List: GET `/configs/`
* Create: POST `/configs/`
* Update All Fields: PUT `/configs/<config-id>`
* Update Selective Fields: PATCH `/configs/<config-id>`
* Delete: DELETE `/config-types/<config-id>`
* Properties
* Configs support the standard properties (id, createdAt, updatedAt, tags)
* name - type: string, constraints: unique
* type - type: string. May be a config type id or config type name
* data - type: JSON object
* Support values are strings, numbers, booleans and nested objects/maps
The ziti CLI supports the following operations on configs:
* create config
* update config
* list configs
* delete config
$ ziti edge controller create config ssh ziti-tunneler-client.v1 '{ "hostname" : "ssh.mycompany.com", "port" : 22 }'
83a1e815-04bc-4c91-8d88-1de8c943545f
$ ziti edge controller list configs
id: 83a1e815-04bc-4c91-8d88-1de8c943545f
name: ssh
type: f2dd2df0-9c04-4b84-a91e-71437ac229f1
data: {
"hostname": "ssh.mycompany.com",
"port": 22
}
$ ziti edge controller update config ssh -d '{ "hostname" : "ssh.mycompany.com", "port" : 2022 }'
Found configs with id 83a1e815-04bc-4c91-8d88-1de8c943545f for name ssh
$ ziti edge controller list configs
id: 83a1e815-04bc-4c91-8d88-1de8c943545f
name: ssh
type: f2dd2df0-9c04-4b84-a91e-71437ac229f1
data: {
"hostname": "ssh.mycompany.com",
"port": 2022
}
$ ziti edge controller delete config ssh
Found configs with id 83a1e815-04bc-4c91-8d88-1de8c943545f for name ssh
$ ziti edge controller list configs
$
Service Configuration
The DNS block, which included hostname and port, has been removed from service definitions. When creating or updating
services, you can submit a configs array, which may include config ids or names (or a mix of the two). Configs are
not required.
NOTE: Only one config of a given type may be associated with a service.
Configurations associated with a service may be listed as entities using:
* List associated configs GET `/services/<config-id>/configs`
Retrieving service configuration
When authenticating, a user may now indicate which config types should be included when listing services.
The authentication POST may include a body. If the body has a content-type of application/json, it will
be parsed as a map. The controller will looking for a key at the top level of the map called configTypes,
which should be an array of config type ids or names (or mix of the two).
Example authentication POST body:
{
"configTypes" : ["ziti-tunneler-client.v1", "ziti-tunneler-client.v2"]
}
When retrieving services, the config data for for those configuration types that were requested will be embedded in
the service definition. For example, if the user has requested (by name) the config types "ziti-tunneler-client.v1" and
"ziti-tunneler-server.v1" and the ssh service has configurations of both of those kinds associated, a listing which
includes that service might look as follows:
{
"meta": {
"filterableFields": [
"id",
"createdAt",
"updatedAt",
"name",
"dnsHostname",
"dnsPort"
],
"pagination": {
"limit": 10,
"offset": 0,
"totalCount": 1
}
},
"data": [
{
"id": "2e79d56a-e37a-4f32-9769-f934976843d9",
"createdAt": "2020-01-23T20:08:58.634275277Z",
"updatedAt": "2020-01-23T20:08:58.634275277Z",
"_links": {
"edge-routers": {
"href": "./services/2e79d56a-e37a-4f32-9769-f934976843d9/edge-routers"
},
"self": {
"href": "./services/2e79d56a-e37a-4f32-9769-f934976843d9"
},
"service-policies": {
"href": "./services/2e79d56a-e37a-4f32-9769-f934976843d9/identities"
}
},
"tags": {},
"name": "ssh",
"endpointAddress": "tcp:localhost:22",
"egressRouter": "cf5d76cb-3fff-4dce-8376-60b2bfb505a6",
"edgeRouterRoles": null,
"roleAttributes": null,
"permissions": [
"Dial"
],
"config": {
"ziti-tunneler-client.v1": {
"hostname": "ssh.mycompany.com",
"port": 22
},
"ziti-tunneler-server.v1": {
"protocol" : "tcp",
"hostname": "ssh.mycompany.com",
"port": 22
}
}
}
]
}
Identity Service Configuration
Configuration for a service can also be specified for a given identity. If a configuration is specified for a service, it will replace any configuration of that type on that service.
* Endpoint /identities/<identityId/service-configs
* Supported operations
* GET returns the array of
* POST will add or update service configurations for the identity
* If a configuration has the same type as another configuration on the same service, it will replace it
* DELETE
* if given an array of service configs, will delete any matching entries
* If given an empty body or empty array, all service configurations will be removed from the identity
* Data Format all operations take or return an array of objects with service and config parameters
* service may be a service name or id. If there are id and name collisions, id will take precedence
* config may be a config name or id. If there are id and name collisions, id will take precedence
* Ex: [{"service": "ssh", "config" : "my-custom-ssh-config" }]
Policy Changes
Syntax Changes
- Roles are now prefixed with
#instead of@ - Ids previously did not require a prefix. They now require an
@prefix - Entities could previously only be referenced by id. They can now also be referenced by name.
- Like ids, names must be prefixed with
@. Entity references will first be check to see if they are a name. If no name is found then they are treated as ids.
Entity Reference by Name
Previously, entities could be referenced in policies by id. They can now also be referenced by name, using the same
syntax. So a service named "ssh" can be referenced as @ssh. If the entity is renamed, the policy will be updated
with the updated name.
If a reference matches both a name and an ID, the ID will always take precedence.
Any Of Semantics
Previously polices operated using 'all of' semantics. In other words, to match a policy, an entity had to have ALL OF the role attributes specified by the policy or be listed explicitly by id.
Edge Router and Service policies now have a new field semantics, which may have values of AnyOf or AllOf. If no
value is provided, it will default to the original behavior of AllOf. If AnyOf is provided then an entity will match
if it matches any of the roles listed, or if it is listed explicitly by id or name.
NOTE
Because service edgeRouterRoles are not broken out into a separate policy entity, they do not support AnyOf semantics.
#All limitations
Because having #all grouped with other roles or entity references doesn't make any sense, #all policies must now be
created with no other roles or entity references.
Service Edge Router Policy
Previously services could be confgured with edge router roles, which limited which edge routers could be used to dial or bind the service.
In 0.9 that is replaced with a new standalone type: service edge router policies. A service edge router policy has three attributes:
- Name
- Service Roles
- Edge Router Roles
An service can be a member of multiple policies and will have access to the union of all edge routers linked to from those policies.
There is a new /service-edge-router-policies endpoint which can be used for creating/updating/deleting/querying service edge router policies. Service edge router policies PUT/POST/PATCH all take the following properties:
- name
- edgeRouterRoles
- serviceRoles
- tags
IMPORTANT NOTES
1. Previously edge router roles on service could be left blank, and the service would be allowed access to all edge routers. Now, a service must be included in at least one service edge router policy or it cannot be dialed or bound.
1. The set of edge routers an identity can use to dial/bind a service is the intersection of the edge routers that the identity has access to via edge router policies and the edge routers that the service has access to via service edge router policies
CLI Updates
The CLI now has # create service-edge-router-policy # list service-edge-router-policies # list service-edge-router-policy services # list service-edge-router-policy edge-routers # list services service-edge-router-policies # list edge-router service-edge-router-policies # delete service-edge-router-policy
Session Types
Previously when creating a session a flag named hosting was provided to indicate if this was a Dial or Bind session.
Now a field named type should be provided instead with Dial and Bind being accepted values. If no value is provided
it will default to Dial.
Ex:
{
"serviceId" : "a5a0f6af-c833-4961-be0a-c7fb093bb11e",
"type" : "Dial"
}
Similarly, when sessions were listed, they had a hosting flag, which has been replaced by a type flag.
NOTE: Finally when sessions are transmitted between the controller and edge router, the format has also switched from using a hosting flag to a type field. This means that controllers and edge routers will not inter-operate across the the 0.9 version boundary.
Release 0.8
Theme
- Ziti 0.8.0 replaces appwans with role attribute based service policies
- Ziti 0.8.0 consolidates dial and bind permissions into service policies
Service Policy
In 0.7.0 and prior access to services was controlled by appwans.
- Appwans had lists of identities and services
- Identities and services could be associated with 0-n appwans
- Services had explicit lists of identities that could bind the service
- In order to dial a service, the identity had to be an admin or be in at least one appwan with that service
- In order to bind a serivice, the identity had to be able to dial the service and be in the list of identities allowed to bind the service
Release 0.8.0 replaces this model with something new. It has the following goals:
- Allow grouping identities and services dynamically using role attributes rather than hard-coded lists
- Consolidate dial and bind permissions into the same model
The following concepts were introduced in 0.7 for edge router policies. They are now used for service policies as well.
- Role attributes
- Role attributes are just a set of strings associated to a model entity
- The semantics of the role attributes are determined by the system administrator
- Ex: an edge router might have the role attributes
["us-east", "new-york", "omnicorp"] - These tags might indicate that this edge router is located on the east coast of the USA, specifically in New York and should be dedicated to use by a customer named OmniCorp
- Currently role attributes are supported on edge routers and identities
- Roles
- Roles specify a set of entities
- Roles may include role attributes as well as entity ids
- A role will match all entities which either:
- Have all role attributes in the role OR
- Have an ID which is listed explicitly
- Role attributes are prefixed with
@. Role elements not prefixed with@are assumed to be ids - There is a special role attribute
@allwhich will match all entities - A role may have only role attributes or only ids or may have both
Role Example
- Service with id 1 has role attributes
["sales", "New York City"] - Service with id 2 has role attributes
["sales", "Albany"] - Service with id 3 has role attributes
["support", "Los Angeles"] - A service role of
["@sales", "@New York City", "3"]would evaluate as follows- Service 1 would match because it has all listed role attributes
- Service 2 would not match, because it doesn't have all listed role attributes
- Service 3 would match because its ID is listed explicitly
Model Changes
Session Names
- api sessions had two endpoints in 0.7,
/api-sessionsand/sessionswhich was deprecated./sessionsis now no longer valid for api sessions - sessions used the
/network-sessionsendpoint. In this release,/network-sessionshas been deprecated and/sessionsshould be used instead. /current-sessionis now/current-api-session
Session Format
- When creating a session, the returned JSON has the same base format as when listing sessions, so it now includes the service and api-session information. The only difference is that the session token is also returned from session create, but not when listing sessions.
- The gateways attribute of session has been renamed to edgeRouters.
Role Attributes
Services now have a roleAttributes field. Identities already had a roleAttributes field, for used with edge router policies.
Service Policies
0.8.0 introduces a new model construct, the Service Policy. This entity allows restricting which services identities are allowed to dial or bind. A service policy has four attributes:
- Name
- Policy Type ("Bind" or "Dial")
- Identity Roles
- Service Roles
An identity can be a member of multiple policies and will have access to the union of all services linked to from those policies.
There is a new /service-policies endpoint which can be used for creating/updating/deleting/querying service policies. Service policies PUT/POST/PATCH all take the following properties:
- name
- type
- valid values are "Bind" and "Dial"
- identityRoles
- serviceRoles
- tags
There are also new association endpoints allowing the listing of services and identities associated with service policies and vice-versa.
- /service-policies//services
- /service-policies//identities
- /identities//service-policies
- /services//service-policies
Service Access
- An admin may dial or bind any service
- A non-admin identity may dial any service it has access to via service policies of type "Dial"
- A non-admin identity may bind any service it has access to via service policies of type "Bind"
When listing services, the controller used to provide a hostable flag with each service to indicate if the service could be bound in addition to being dialed. Now, the service will have a permissions block which will indicate if the service may be dialed, bound or both.
Ex:
{
"meta": {},
"data": {
"id": "1012d4d7-3ab3-4722-8fa3-ae9f4da3c8ba",
"createdAt": "2020-01-04T02:34:00.788444359Z",
"updatedAt": "2020-01-04T02:34:00.788444359Z",
"_links": {
"edge-routers": {
"href": "./services/1012d4d7-3ab3-4722-8fa3-ae9f4da3c8ba/edge-routers"
},
"self": {
"href": "./services/1012d4d7-3ab3-4722-8fa3-ae9f4da3c8ba"
},
"service-policies": {
"href": "./services/1012d4d7-3ab3-4722-8fa3-ae9f4da3c8ba/identities"
}
},
"tags": {},
"name": "cac9593c-0494-4800-9f70-c258ff28a702",
"dns": {
"hostname": "0bf71754-ed5b-4b2d-9adf-a542f1284275",
"port": 0
},
"endpointAddress": "4662d564-3fc3-4f10-b8cd-ee0e3629ad24",
"egressRouter": "aedab92f-2ddf-445a-9194-73d428322a34",
"edgeRouterRoles": null,
"roleAttributes": [
"2c68789a-fe71-4d25-a483-43e54ee4fd98"
],
"permissions": [
"Bind"
]
}
}
Appwan Removal and Migration
The /app-wans endpoint has been removed. The bbolt schema version has been bumped to 3. If starting a fresh controller no action will be taken. However, if coming from an existing 0.7 or earlier bbolt database, the following will be done:
- For each existing appwan, a service policy with type "Dial" will be created
- The new service policy will have the same name as the appwan it replaces
- The new service policy will have the same identities and services as the appwan it replaces
- Identities and services will be specified explicitly by ID rather as opposed to by creating new role attributes
NOTE: Service hosting identities will not be migrated into equivalent Bind service policies, as binds are not yet used in any production scenarios.
Go SDK changes
Several types have been renamed to conform to standard nomenclature
- Session is now ApiSession
- NetworkSession is now Session
- The SessionId field is now ApiSessionId
- The Gateways field is now EdgeRouters
- Gateway is now EdgeRouter
- On the Service type the Hostable flag has been removed and replaced with a Permissions string array
- It may be nil, empty or contain either or both of "Dial" and "Bind"
- On the Context type
- GetNetworkSession is now GetSession
- GetNetworkHostSession is now GetBindSession
ziti command line changes
- The
ziti edge controller create/delete gatewaycommands have been removed. Useziti edge controller create/delete edge-routerinstead. - There are new
ziti edge controller create/delete service-policycommands
Ziti Proxy changes
ziti-proxy has been incorporated into the ziti-tunnel command. Where previously one would have run
ZITI_SDK_CONFIG=./config.json ziti-proxy run <proxied services>
now one should use
ziti-tunnel proxy -i ./config.json <proxied services>
Release 0.7
Theme
- Ziti 0.7.0 replaces clusters with role attribute based policies
- Ziti 0.7.0 takes steps towards consistent terminology for sessions
Edge Router Policy
In 0.6.0 access to edge routers was controlled by clusters and services.
- Every edge router was assigned to a cluster
- Services belonged to 1 or more clusters
- Dial/bind request would results would include a list of edge routers which were
- in clusters linked to the dialed/bound service and
- were online when the request was made
Release 0.7.0 replaces this model with something new. It has the following goals:
- Allow grouping edge routers and other entities dynamically using role attributes rather than hard-coded lists
- Allow restricting access to edge router by identity in addition to by service
It includes the following new concepts:
- Role attributes
- Role attributes are just a set of strings associated to a model entity
- The semantics of the role attributes are determined by the system administrator
- Ex: an edge router might have the role attributes
["us-east", "new-york", "omnicorp"] - These tags might indicate that this edge router is located on the east coast of the USA, specifically in New York and should be dedicated to use by a customer named OmniCorp
- Currently role attributes are supported on edge routers and identities
- Roles
- Roles specify a set of entities
- Roles may include role attributes as well as entity ids
- A role will match all entities which either:
- Have all role attributes in the role OR
- Have an ID which is listed explicitly
- Role attributes are prefixed with
@. Role elements not prefixed with@are assumed to be ids - There is a special role attribute
@allwhich will match all entities - A role may have only role attributes or only ids or may have both
Role Example
- Edge router with id 1 has role attributes
["us-east", "New York City"] - Edge router with id 2 has role attributes
["us-east", "Albany"] - Edge router with id 3 has role attributes
["us-west", "Los Angeles"] - An edge router role of
["@us-east", "@New York City", "3"]would evaluate as follows- Edge router 1 would match because it has all listed role attributes
- Edge router 2 would not match, because it doesn't have all listed role attributes
- Edge router 3 would match because its ID is listed explicitly
Model Changes
Role Attributes
Edge routers and identities now have roleAttributes fields. Edge routers no longer have an associated cluster.
Edge Router Policies
0.7.0 introduces a new model construct, the Edge Router Policy. This entity allows restricting which edge routers identities are allowed to use. An edge router policy has three attributes:
- Name
- Identity Roles
- Edge Router Roles
An identity can be a member of multiple policies and will have access to the union of all edge routers linked to from those policies.
There is a new /edge-router-policies endpoint which can be used for creating/updating/deleting/querying edge router policies. Edge router policies PUT/POST/PATCH all take the following properties:
- name
- edgeRouterRoles
- identityRoles
- tags
Service Edge Router Roles
Services now have a new edgeRouterRoles field. If set, this specifies which edge routers may be used for a service. This replaces the old cluster functionality.
Edge Router Access
When a service is dialed or bound, which edge routers will be returned?
- If the service edgeRouterRoles are NOT set, then it will be the set of edge routers to which the dialing/binding identity has access
- If the service edgeRouterRoles ARE set, then it will be the intersection of the edge routers to which the service has access and the set of edge routers to which the identity has access
Cluster Removal and Migration
The /clusters endpoint has been removed. The bbolt schema version has been bumped to 2. If starting a fresh controller no action will be taken. However, if coming from an existing 0.6 or earlier bbolt database, the following will be done:
- An edge router policy will be created with
@allfor both identityRoles and edgeRouterRoles, allowing access to all edge routers from all identities. This will allow the current identities to continue using the system. Otherwise, no identities would be able to connect to any edge routers. - Each edge router will get a role attribute of
cluster-<cluster name>for the cluster it belonged to - If a service belongs to 1 or more clusters it will get a role attribute corresponding to the first cluster. Any edge routers assigned to additional clusters will be added to edge router roles field by ID.
- Noe: If we were to add additional role clusters for the other clusts we'd get the intersection, not the union and would end up with access to 0 edge routers
Session changes
Terminology related to sessions is being made consistent between the edge and fabric.
There are two types of sessions:
- Sessions between edge clients the edge controller, which allowed clients to manage controller state as well as dial and bind services
- These were referred to as sessions in the edge and have no fabric equivalent
- Sessions which establish routing and allow data flow to/from/within the edge and fabric
- These were referred to as network sessions in the edge and sessions in the fabric
Going forward, what was called a session in the edge will now be referred to as an API session. What was called a network session will be now just be called session in both the edge and fabric.
As a first step, in 0.7.0 API sessions will be available at both the /sessions and /api-sessions endpoints. Use of the /sessions endpoint is deprecated. In later releases the /sessions endpoint will be used for sessions instead of API sessions.
Release 0.6
Theme
Ziti 0.6.0 moves the back-end persistence model of Ziti Edge and Ziti Fabric into the same repository based on Bbolt (an in memory data store that is backed by a memory mapped file). The changes remove the requirement for PostgresSQL.
UPDB Enrollment JWTs
Enrollments that are for UPDB (username password database) are now consistent with all other enrollment and use JWTs for processing. Prior to this a naked URL was provided.
What This Breaks
Any UPDB enrollment processing that relied upon the URL for the enrollment.
Ziti 0.5.x UPDB enrolling entity
{
"meta": {},
"data": {
"id": "612843ae-6ac8-48ac-a737-bfc2d28ab9ea",
"createdAt": "2019-11-21T17:23:00.316631Z",
"updatedAt": "2019-11-21T17:23:00.316631Z",
"_links": {
"self": {
"href": "./identities/612843ae-6ac8-48ac-a737-bfc2d28ab9ea"
}
},
"tags": {},
"name": "updb--5badbdc5-e8dd-4877-82df-c06aea7f1197",
"type": {
"id": "577104f2-1e3a-4947-a927-7383baefbc9a",
"name": "User"
},
"isDefaultAdmin": false,
"isAdmin": false,
"authenticators": {},
"enrollment": {
"updb": {
"username": "asdf",
"url": "https://demo.ziti.netfoundry.io:1080/enroll?method=updb&token=911e6562-0c83-11ea-a81a-000d3a1b4b17&username=asdf"
}
},
"permissions": []
}
}
Ziti 0.6.x UPDB enrolling entity (note the changes in the enrollment.updb object):
{
"meta": {},
"data": {
"id": "39f11c10-0693-41ed-9bec-8011e2721562",
"createdAt": "2019-11-21T17:28:18.2855234Z",
"updatedAt": "2019-11-21T17:28:18.2855234Z",
"_links": {
"self": {
"href": "./identities/39f11c10-0693-41ed-9bec-8011e2721562"
}
},
"tags": {},
"name": "updb--b55f5372-3993-40f5-b534-126e0dd2f1be",
"type": {
"entity": "identity-types",
"id": "577104f2-1e3a-4947-a927-7383baefbc9a",
"name": "User",
"_links": {
"self": {
"href": "./identity-types/577104f2-1e3a-4947-a927-7383baefbc9a"
}
}
},
"isDefaultAdmin": false,
"isAdmin": false,
"authenticators": {},
"enrollment": {
"updb": {
"expiresAt": "2019-11-21T17:33:18.2855234Z",
"issuedAt": "2019-11-21T17:28:18.2855234Z",
"jwt": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbSI6InVwZGIiLCJleHAiOjE1NzQzNTc1OTgsImlzcyI6Imh0dHBzOi8vbG9jYWxob3N0OjEyODAiLCJqdGkiOiJiYzBlY2NlOC05ZGY0LTQzZDYtYTVhMC0wMjI1MzY2YmM4M2EiLCJzdWIiOiIzOWYxMWMxMC0wNjkzLTQxZWQtOWJlYy04MDExZTI3MjE1NjIifQ.PUcnACCdwqfWRGRzF8lG6xDTgHKAwKV6eTw8tHFuNBXaUNbqExBwUQEW0-cCHsV-nLEyhxyjhXmVCkIDgz-ukKfS0xStiDrJQbiq8m0auodkArmJSsYzElXkKdv37FHu0t-CGoXptdLyuo9eCnzzmci3ev18zMR5HjYMCQEclELV6OEICNr_0EwhAGJa1yX6ODYrLMZ3SdEd6fj-ZGX7j9owTs6iEsqCB_TORfnGGg6lEINE5GlYsyp7JUxolS6H4lPeN5h2mxk2_OkJY8GX3ydv75LsIZ-jjL3xC5XncCESrefgDabib1fudJ4038D0EzqTcOREPAqmjWhnDhTulQ",
"token": "bc0ecce8-9df4-43d6-a5a0-0225366bc83a"
}
},
"permissions": []
}
}
What To Do
Use the new JWT format to:
verify the signature of the JWT to match the iss URL's TSL presented certificates construct the enrollment url from the JWTs properties in the following format:
<iss> + "/enroll?token=" + <jti>
Multiple Invalid Value Error Handling
Errors where there is the potential to report about multiple invalid field values for a given field used to report as a separate error for each value. Now there will be one error, but the values field will hold the invalid values.
Old Format
{
"error": {
"args": {
"urlVars": {
"id": "097018b6-108e-42b3-869b-deb9e1814594"
}
},
"cause": {
"errors": [
{
"message": "entity not found for id [06ecf930-3a9f-4a6c-98b5-8f0be1bde9e2]",
"field": "ids[0]",
"value": "06ecf930-3a9f-4a6c-98b5-8f0be1bde9e2"
}
]
},
"causeMessage": "There were multiple field errors: the value '06ecf930-3a9f-4a6c-9...' for 'ids[0]' is invalid: entity not found for id [06ecf930-3a9f-4a6c-98b5-8f0be1bde9e2]",
"code": "INVALID_FIELD",
"message": "The field contains an invalid value",
"requestId": "48ea4bce-f233-410e-a062-5dbceee20223"
},
"meta": {
"apiEnrolmentVersion": "0.0.1",
"apiVersion": "0.0.1"
}
}
New Format
{
"error": {
"args": {
"urlVars": {
"id": "5b15c442-5590-4c58-8bc7-0da788e0cfcf"
}
},
"cause": {
"message": "clusters(s) not found",
"field": "clusters",
"value": [
"68f8739f-cf52-4d51-9553-dfe7cf9c6a03"
]
},
"causeMessage": "the value '[68f8739f-cf52-4d51-9553-dfe7cf9c6a03]' for 'clusters' is invalid: clusters(s) not found",
"code": "INVALID_FIELD",
"message": "The field contains an invalid value",
"requestId": "ab6553e8-e9b1-408c-9fed-11cc627cfd84"
},
"meta": {
"apiEnrolmentVersion": "0.0.1",
"apiVersion": "0.0.1"
}
}