-
Notifications
You must be signed in to change notification settings - Fork 19
Continuous Authentication Thoughts
There are a couple of different kinds of continuous authentication that we want to support.
A rules engine could change policies or re-evaluate policies based on different criteria, including:
- time
- SDK submitted information
- generic events, which could be triggered in a number of ways, including changes to external systems (LDAP/AD/Identity providers)
It would be useful to allow or deny access based on different time based criteria
- Access granted/denied between these times of day
- Access granted/denied these days of the week
- Access granted/denied between two absolute instants
SDKs can submit arbitrary information during authentication. This information could be used to drive policy for the duration of the API session.
- SDK submits site=Chicago. This allows the identity to use an Edge Router associated with the Chicago site.
- SDK submits OS=Windows. This allows the identity to use a Windows specific service.
- SDK submits MyAppVersion=2.09. This prevents the identity from using a specific service which requires MyAppVersion > 3.05
We can't guarantee that the values submitted by an SDK client are correct. We can provide a way for them to be signed and do signature checking. It's up to the client to bootstrap trust on the client.
The SDK could either poll for changes to the embedding application, or have an API to call when changes are detected. The SDK itself could be triggered to poll by the controller or could handle that autonomously.
How to translate rules into policy is also tricky. If rules changed role attributes, that could potentially be slow to process. Also, we would need to track which role attributes came from rules and which didn't so we could clean them up when rules evaluations changes. Finally, if someone were creating multiple concurrent sessions with the same identity, they could end up with inconsistent data.
However, if we creating a temporary mapping on top of the existing policy system, that could also be confusing. Filtering or mutating lists of services or edge routers would be easy to get wrong.
A primary driver here is performance. Any policy evaluation must happen before sessions can be established. This could be done by requiring evaluation to happen during authentication. Alternatively, we could mark the API session as unready until evaluation is done and either block or fail new dial/bind sessions until the evaluation is complete.
Either way, policy changes (whether direct or via a layer) would need to be fast so that we don't have to block access to services until evaluation is complete.
Another way to implement this would be to allow specifying identity role attributes.
The SDK could submit roleAttributes=chicago,os-windows. These would be added to the role attributes and policies would be re-evaluated. It would be difficult to do something like the MyAppVersion example above. You could have rules and policies for each version of an application, or do something like have an attribute for each major version of an application.
SDK submitted attributes would have to be separate from regular attributes, maybe referenced in policies using a prefix sdk:chicago
, otherwise SDK users could subvert policies.
A Ziti admin might want to integrate with ID/Authorization/Authentication provider.
If the auth provider has a feed of events, we could use the feed to add/remove users as well as sync role attributes with some system of record. This would existing Ziti APIs and shouldn't require any additional development to support.
If we have a rules engine, we could also have an API for generating events to feed the rules engine.
Ziti administrators may want to add hooks which will allow checks at specific points of use. For example, when authenticating, checking that a corresponding records exists in some external system. When using a service or edge router, checking that the pair in some external resource.
To implement this we'd like want to create some interface
type ExternalAuthenticator interface {
CheckCreateApiSession(identity *model.Identity) error
CheckServiceAccess(identity *model.Identity, service *model.Service) error
CheckEdgeRouterAccess(identity *model.Identity, edgeRouter *model.EdgeRouter) error
}
We already have an AuthProcessor
interface. This would need to be called in addition to that. The downside to the 'time of use' approach is that services and edge routers that an identity might not have access to would still show up in lists, but attempts to use them would fail.