Licensing Architecture
There will be two different layers of licensing/protection:
- Application layer – license validation/checks embedded into application flow
- Orchestration layer – assembly’s signature, containers signature, 3rd party services security. Mostly DevOps stream
Application layer
License will be a base64 encoded token that contains:
- Tenant identification (tenantGlobalID)
- List of features enabled for the tenant
- Capacity information (e.g. number of concurrent calls, number of active users, etc)
- Signature – hash that’s calculated with using signing certificate on in-house licensing server
Signature is validated by the public key of signing certificate that is known by all services.
License service will have three parts:
- API - endpoints for updating the system license and for getting the usage report
- Subscriber - service that gets "license usage" events and store them into encrypted database
- Encrypted DB - SQL Lite database with enabled encryption, Will be used to store usage events
Distribution
New licenses is distributed via License API endpoint that do a basic validation (all business requirements will be added later – e.g. number of active users more than in the new license).
After validation license token is put into a separate stream in the Event Store where it can be read by concerned services. Service do a basic validation (signature and expiration), apply it to the in-memory license and store as a file on disk
Metered License
Main concern with the metered license is “on demand” installation where customer has full access to the infrastructure, so the main idea here is to reduce levels of attack as much as possible.
If the license for some resource is exceeded, concerned service put a "license usage" event to the separate stream in the EventStore and wait for the response from the Licensing Service.
Event contains following information:
- Key for the entity (e.g. users, number of parallel calls, etc)
- Value – how many entities does customer have right now
- Timestamp
- Signature – hash that generated from the key, value and shared secret (probably public key of signing certificate can be used)
Such blocking operations on the service side could bring performance issues for recording, so for some operations we would need to put this event asynchronously and not await for the licensing service's response. Potentially, if users has access to the event store they could delete this event before it consumed by the licensing service, but we assume that all 3rd party services will be secured and admin username/password won't be exposed to the user. Licensing Service put this information into encrypted database that is generated first time service is deployed. During initialization of encrypted data base licensing service puts a timestamp of creation that will be used for the validating that db hasn't been changed or deleted.
Main requirement for the metered license is ability to work in offline, so we can't make any health check requests or scheduled requests to the in-house licensing server, so the only ability to transfer usage information will be a "Usage Report" that is generated by Licensing Service. It contains the following information:
- DB timestamp. It will be used on the licensing server side to check whether DB has been updated
- Usage report. List of "license usage" events (key/value)
- Signature. Signature that can be checked on the "in-house" licensing server side
Per Channel License
Per channel license means number of concurrent unique calls (unique CallID) we can have simultaneously.
It will be checked on the consumers side, metadata consumer will check whether we haven't hit the limit of concurrent calls and will rise a usage event (for metered license)
Per User License
“Per user” license will be handled on the Identity Services side. During creating user service would check if user tries to create a disabled user then just save as disable, if user tries to save active user then:
- If license is valid, but users limit is reached than put disabled user
- If license is valid and user can be added, user is added with active state
Validation will be done on the Consumer services side (MetadataConsumer/MediaConsumer). Collector will send agent extention that will be used to get agent and user entities per call.
Per Device
"Per Device" license will be handled on the Configuration Side, endpoint "Devices". Logic is similar to the Per User implementation - service will validate license limitations and will add device as active or inactive.
Validation will be done on the Consumer services side (MetadataConsumer/MediaConsumer). Collector will send device ID as part of the call metadata, it will be used to check if device is active and if not active - skip the call
Feature Per User
Each feature per user will be handled by roles and permissions. Each time we assign role to the user we check if license is not exceeded for particular permission. E.g. before assigning role that has call suppression permission to the user, system would check if this feature is licensed to the tenant and check the number of users that already have this permission assignment, if number is lower than in the license, role is assigned otherwise we get an error.