How to Setup

The rules are defined by a filtering strategy and the logic which can be configured based on your specific use case. The strategy ensures that only an identified person will pass the access barrier in the right time without stoppage or any further action.

Applying Filtering Strategies

SmartFace Access Controller supports wide range of configuration in order to fullfil range of requirements. In generally, configuration is done via configuration file or environment variables. The configuration method differs between the Microsoft Windows and the Docker versions.

Windows Application

Configuration of the AccessController running on Windows is located in config file appSettings.json is usually located at C:\Program Files\Innovatrics\Access Controller and has structure of a JSON. File is locked for write and requires administrator’s privilegs to be overwritten.

Docker on Linux

The AccessController running in Docker on Linux has by default configuration stored in .env.sfac file located allongside the docker-compose.yml file. The format used is such as the Docker environment variables.

Configurable Options

Each option can be configured separately, by using bool value true and false for the option’s enablement variable. For example to enable the Face order, use line as below. The example uses the Docker version of the configuration.

FilterConfiguration__FaceOrderConfiguration__Enabled=true

If you would like to keep it disabled, please use line as below:

FilterConfiguration__FaceOrderConfiguration__Enabled=false

To achieve the desired result a mixing combination of various options can be applied at the same time. Please see the description of the available options below.

Face Order

This filter is used for filtering out faces which are not detected closest to the camera. It ensures that Access Controller sends an access-granted notification only for a person who is the nearest to the access point. Access Controller sends an access-granted notification only if the detected face on the incoming video stream has the order (in terms of distance from the camera) equal to the configured value. The default value of the order is 1. Therefore, only to the closest detected face is granted the access.

Face Order

Environment Variable
FilterConfiguration__FaceOrderConfiguration__Enabled=false
FilterConfiguration__FaceOrderConfiguration__Order=1
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "FaceOrderConfiguration": {
            "Enabled": true,
            "Order": 1
        },
        ...
    }
    ...
}

Opening Debounce

This filter is used for filtering out multiple notifications which are sent for the same person for a predefined time period. Access Controller sends an access-granted notification only when a predefined interval has passed since the last granted access for the respective person. The default interval for the debounce time is 4000 ms. This filter prevents multiple openings for the same person in a short time interval.

Environment Variable
FilterConfiguration__OpeningDebounceConfiguration__OpeningDebounceEnabled=true
FilterConfiguration__OpeningDebounceConfiguration__OpeningDebounceMs=4000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "OpeningDebounceConfiguration": {
            "OpeningDebounceEnabled": true,
            "OpeningDebounceMs": 4000
        },
        ...
    }
    ...
}

Blocking Debounce

This filter is similar to OpeningDebounceFilter but it filters block notifications. The default interval for the debounce time is 4000 ms. This filter prevents multiple block notifications being sent for the same person in a short time interval.

Environment Variable
FilterConfiguration__BlockingDebounceConfiguration__BlockingDebounceEnabled=true
FilterConfiguration__BlockingDebounceConfiguration__BlockingDebounceMs=4000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "BlockingDebounceConfiguration": {
            "BlockingDebounceEnabled": true,
            "BlockingDebounceMs": 4000
        },
        ...
    }
    ...
}

Exclusive camera

After granting access to an identified person to a particular access point, Access Controller filters out notifications for opening of all other access points for this person for a predefined time period. The default value for blocking of other access points is 5000 ms. This filter ensures that a person who turned around after passing the access point isn’t detected again and the access point won’t open for this person in the opposite direction.

Environment Variable
FilterConfiguration__ExclusiveCameraConfiguration__Enabled=true
FilterConfiguration__ExclusiveCameraConfiguration__ExclusivityMs=5000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "ExclusiveCameraConfiguration": {
            "Enabled": true,
            "ExclusivityMs": 5000
        },
        ...
    }
    ...
}

Not identified person configuration

This filter is used for filtering out incoming NoMatch notifications and for sending an access-denied notification, when a detected person is continuously unidentified for a predefined time period and when this person’s face was the nearest to the camera. NotIdentifiedPersonFilter is defined by the RoamingLimitTimeMs parameter with a default value of 3000 ms. This filter ensures that the user is notified only once per a defined time period about an unknown person and is not overwhelmed by NoMatch notifications.

Environment Variable
FilterConfiguration__NotIdentifiedPersonConfiguration__Enabled=true
FilterConfiguration__NotIdentifiedPersonConfiguration__RoamingLimitTimeMs=3000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "NotIdentifiedPersonConfiguration": {
            "Enabled": true,
            "RoamingLimitTimeMs": 3000
        },
        ...
    }
    ...
}

Blacklist configuration

This filter sends an access-blocked notification when an identified person belongs to a watchlist specified as a blacklist. The filter ensures that the user is notified about a disapproved and restricted person detected in front of the access point. Watchlists specified as blacklists can be listed in the configuration. There is no default blacklist configured.

Environment Variable
FilterConfiguration__BlacklistsConfiguration__Enabled=true
FilterConfiguration__BlacklistsConfiguration__Blacklists__0=first_black_list_id
FilterConfiguration__BlacklistsConfiguration__Blacklists__1=second_black_list_id
FilterConfiguration__BlacklistsConfiguration__Blacklists__2=third_black_list_id
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "BlacklistsConfiguration": {
            "Enabled": true,
            "Blacklists": [ "first_black_list_id", "second_black_list_id", "third_black_list_id" ]
        },
        ...
    }
    ...
}

Face mask configuration

Ensures that the access is denied to an identified person who is trying to access the premises but doesn’t wear a face mask. The access-denied notification is sent every 4000 ms which is configurable by the DenyingDebounceMs parameter. This filter allows you to enforce rules on wearing face masks due to epidemics or pandemics.

Environment Variable
FilterConfiguration__FaceMaskConfiguration__Enabled=false
FilterConfiguration__FaceMaskConfiguration__DenyingDebounceMs=4000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "FaceMaskConfiguration": {
            "Enabled": true,
            "DenyingDebounceMs": 4000
        },
        ...
    }
    ...
}

Intentional access configuration

This configuration enables access for persons intending to enter the premises. Currently, it operates in two steps:

  1. Access is granted if the face size as captured by the camera is equal to or larger than AlwaysOpenForFaceSizeLargerThan.
  2. Alternatively, if the person’s face size at a future point, estimated by the Access Controller based on their approach speed and configured prediction time (PredictionMilliseconds), exceeds the threshold specified by AlwaysOpenForFaceSizeLargerThan, access is also granted.

This configuration will filter people lingering in camera frame, but will grant access to people approaching the camera in advance.

Environment Variable
FilterConfiguration__IntentionalAccessConfiguration__AlwaysOpenForFaceSizeLargerThan=160
FilterConfiguration__IntentionalAccessConfiguration__PredictionMilliseconds=1500
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "IntentionalAccessConfiguration": {
            "Enabled": false,
            "AlwaysOpenForFaceSizeLargerThan": 160,
            "PredictionMilliseconds": 1500
        },
        ...
    }
    ...
}

Stream group configuration

When one camera in a group signals to open, then all cameras from the same group will not signal an open for 3000 ms configurable by the GroupOpeningDebounceMs parameter. This is introduced to support a use case when one gate is accessible from both directions (in and out) and two people simultaneously try to enter and exit. In such a case only the first person opens the gate and the second one will have to wait for the configurable time. This is done so that the gate does not try to open in both directions simultaneously.

Environment Variable
FilterConfiguration__StreamGroupsConfiguration__Enabled=true
FilterConfiguration__StreamGroupsConfiguration__GroupOpeningDebounceMs=3000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "StreamGroupsConfiguration": {
            "Enabled": true,
            "GroupOpeningDebounceMs": 3000
        },
        ...
    }
    ...
}

Liveness / spoofcheck configuration

Ensures that the access is denied to a person who is trying to enter as another person (e.g. by aiming tablet display with a photo to the camera). The access-blocked notification is sent every 4000 ms which is configurable by the DenyingDebounceMs parameter. There is also possibility to enable more sophisticated option - spoof rate limiting strategy by enabling SpoofRateLimitingConfiguration.

Environment Variable
FilterConfiguration__SpoofCheckConfiguration__Enabled=false
FilterConfiguration__SpoofCheckConfiguration__DenyingDebounceMs=4000
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__Enabled=false
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__SpoofAttemptsCount=2
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__SpoofAttemptsWindowMs=120000
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__BlockingTimeIncrementCooldownMs=10000
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__BlockingTimeIncrementMs=30000
FilterConfiguration__SpoofCheckConfiguration__SpoofRateLimitingConfiguration__MaxBlockingTimeMs=300000
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "SpoofCheckConfiguration": {
            "Enabled": false,
            "DenyingDebounceMs": 4000,
            "SpoofRateLimitingConfiguration": {
                "Enabled": false,
                "SpoofAttemptsCount": 2,
                "SpoofAttemptsWindowMs": 120000,
                "BlockingTimeIncrementCooldownMs": 10000,
                "BlockingTimeIncrementMs": 30000,
                "MaxBlockingTimeMs": 300000
            }
        },
        ...
    }
    ...
}

Expression configuration

The expression configuration feature is available since version 5.4.19.

You are able to detect and evaluate expression - angles between your face and the camera (the pitch and yaw angles) and the face size being detected. By enabling this configuration the access will be granted only to the person who’s expression fits within the set constrains.

Environment Variable
FilterConfiguration__ExpressionConfiguration__Enabled=false
FilterConfiguration__ExpressionConfiguration__Expression="props.YawAngle >= -20 && props.YawAngle <= 20 && props.PitchAngle >= -20 && props.PitchAngle <= 20 && props.FaceSize >= 60"
AppSettings.json
{
    ...    
    "FilterConfiguration": {
        ...
        "ExpressionConfiguration" : {     
            "Enabled" : false,
            "Expression" : "props.YawAngle >= -20 && props.YawAngle <= 20 && props.PitchAngle >= -20 && props.PitchAngle <= 20 && props.FaceSize >= 60"
        }
    }
}

Expression Configuration explained

Currently is supported filtering by following attributes:

FaceArea, FaceSize,Sharpness,Brightness,TintedGlasses,
HeavyFrame, GlassStatus, YawAngle, PitchAngle, RollAngle, Age, Gender

These attributes are nullable, therefore they can be empty and have null value.

Any of these attributes can be combined together and compared with these operators, expressions also follow standard C# rules for operators precedence, therefore parentheses can be used normally.

CategoryOperators
Relational and type testing< > <= >= is as
Equality== !=
Logical AND&
Logical OR|
Logical XOR^
Conditional AND&&
Conditional OR||
Examples:

Allow passage if YawAngle of face is in range (-10,10):

props.YawAngle > -10 && props.YawAngle < 10

Allow passage if YawAngle and PitchAngle of face is in range (-10,10):

props.YawAngle > -10 && props.YawAngle < 10 && props.PitchAngle > -10 && props.PitchAngle < 10
</span>

Allow passage if Brightness equals 100:

props.Brightness == 100

Require input with Brightness more or equal than 100 and Sharpness needs to be more than 50 and FaceSize needs to be larger than 25px and confidence of HeavyFrame and TintedGlasses needs to be under certain level (100 and 50):

props.Brightness >= 100 && props.Sharpness > 50 && props.FaceSize > 25 && props.HeavyFrame < 100 && props.TintedGlasses < 50

Require Age 18 or above and Female gender

props.Age >= 18 && props.Gender < 0

Require Age 18 or above or Age 18 or less and Male gender

props.Age >= 18 || (props.Age <= 18 && props.Gender > 0)

Configure settings for all cameras/specific camera(s)

If the settings are under the FilterConfiguration then it is applied to all cameras. You can apply camera specific settings that will be applied to a selected camera, overwriting the general settings by using the StreamFilterConfigurations section. Within the StreamFilterConfigurations you need to define a camera stream id that will be used for all the camera specific setup.

Environment Variable
StreamFilterConfigurations__<camera-stream-id1>__SpoofCheckConfiguration__Enabled=true
StreamFilterConfigurations__<camera-stream-id1>__SpoofCheckConfiguration__DenyingDebounceMs=4000
StreamFilterConfigurations__<camera-stream-id2>__SpoofCheckConfiguration__Enabled=true
StreamFilterConfigurations__<camera-stream-id2>__SpoofCheckConfiguration__DenyingDebounceMs=4000
AppSettings.json
{
    ...    
    "StreamFilterConfigurations": {
        "camera-stream-id1" : {
            "SpoofCheckConfiguration": {
                "Enabled": true,
                "DenyingDebounceMs": 4000
            }
        },
        "camera-stream-id2" : {
            "SpoofCheckConfiguration": {
                "Enabled": true,
                "DenyingDebounceMs": 4000
            }
        }
    }
}

Jaeger tracing

These are settings related to tracing for development purposes.

# Set true when a Jaeger tracing is required
AppSettings__USE_JAEGER_APP_SETTINGS=false
AppSettings__JAEGER_SAMPLER_TYPE = const
AppSettings__JAEGER_SAMPLER_PARAM = 1
AppSettings__Log_RollingFile_Enabled = true
AppSettings__Log_JsonConsole_Enabled = false

# Jaeger tracing endpoint. 'jaeger' is the name of included docker container.
# If targeting outside SmartFace docker, change to remote URL
AppSettings__JAEGER_AGENT_HOST = jaeger

API

Access Notification configuration

The Access Controller exposes the gRPC service that is streaming access notifications. GRPC service is hosted inside ASP .NET Core Web Server (Kestrel) and therefore can be configured by modifying Kestrel configuration section in appsettings.json file.

Default Kestrel port is set to 5050 and running as HTTP with localhost (127.0.0.1).

You can write your own application using the access notifications provided. For a sample of code please read about the Relay Connector .

GRPC AccessNotificationService.proto file:

syntax = "proto3";
package innovatrics.smartface;
import "google/protobuf/timestamp.proto";

enum AccessNotificationType
{
	UNSPECIFIED_GRANTED = 0;
	GRANTED = 0x01;
	DENIED = 0x02;
	BLOCKED = 0x04;
	PING = 0x08;
}

enum MaskStatus
{
	UNKNOWN = 0;
	MASK = 1;
	NO_MASK = 2;
}

enum DenyReason
{
	NOT_IDENTIFIED = 0;
	IDENTIFIED_WITH_NO_MASK = 1;
}

enum BlockReason
{
	IDENTIFIED_IN_BLOCK_LIST = 0;
	SPOOF_DETECTED = 1;
	OPENING_TEMPORARILY_BLOCKED = 2;
}

message AccessNotificationRequest
{
	bool send_image_data = 1;
	uint32 type_of_access_notification = 2;
}

message AccessNotification
{
	AccessNotificationGranted access_notification_granted = 1;
	string stream_id = 2;
	string face_id = 3;
	google.protobuf.Timestamp face_detected_at = 4;
	google.protobuf.Timestamp sent_at = 5;
	map<string,string> headers = 6;
	AccessNotificationDenied access_notification_denied = 7;
	uint32 type_of_access_notification = 8;
	//this response type cannot be both GRANTED and DENIED (or BLACKLIST) at the same time
	AccessNotificationBlocked access_notification_blocked = 9;
	string tracklet_id = 10;
	MaskStatus mask_status = 11;
	double face_mask_confidence = 12;
	int64 frame_timestamp_us = 13;
	EyeCoordinates eye_coordinates = 14;
}

message AccessNotificationGranted
{
	string watchlist_member_external_id = 1;
	string watchlist_external_id = 2;
	string watchlist_member_full_name = 3;
	string watchlist_member_id = 4;
	string watchlist_id = 5;
	string watchlist_full_name = 6;
	int64 match_result_score = 7;
	bytes crop_image = 8;
    map<string, string> watchlist_member_labels = 9;
}

message AccessNotificationDenied
{
	bytes crop_image = 1;
	DenyReason reason = 2;
	string watchlist_member_full_name = 3;
	string watchlist_member_id = 4;
	string watchlist_id = 5;
	string watchlist_full_name = 6;
	int64 match_result_score = 7;
}

message AccessNotificationBlocked
{
	string watchlist_member_full_name = 1;
	string watchlist_member_id = 2;
	string watchlist_id = 3;
	string watchlist_full_name = 4;
	int64 match_result_score = 5;
	bytes crop_image = 6;
	BlockReason reason = 7;
	google.protobuf.Timestamp blocked_until = 8;
}

message EyeCoordinates
{
	double left_eye_x = 1;
	double left_eye_y = 2;
	double right_eye_x = 3;
	double right_eye_y = 4;
}

service AccessNotificationService
{
	rpc GetAccessNotifications(AccessNotificationRequest) returns (stream AccessNotification);
}

Access Filters configuration

Access Controller exposes GRPC configuration service that can be used to change access filters configurations at runtime. Configuration messages structure are mimicking default configuration in appsettings.json file.

Configuration persistency

Access Controller currently do not use any kind of database for storing configuration. Default configuration is stored in appsettings.json file and can be overridden by environment variables and command line arguments.

To be able to configure access filters via API and to also always keep default configuration, these filters configuration are stored in separate configuration file called appsettings.FiltersConfiguration.json.

This file is created/deleted/altered by Access Controller itself when GRPC configuration service methods are called.

File location depends on OS that Access Controller is running on:

OSPath
WindowsC:\ProgramData\Innovatrics\AccessController\appsettings.FiltersConfiguration.json
Linux/usr/share/Innovatrics/AccessController/appsettings.FiltersConfiguration.json

Service implementation notes

GRPC configuration service exposes three main API methods.

GetFiltersConfiguration

This methods returns current filters configuration used by Access Controller. It will return either default configuration (if no configuration was changed yet) or configuration that is persisted in appsettings.FiltersConfiguration.json file.

SetFiltersConfiguration

This method accepts configuration message that can define all configuration for filters.

ℹ️ It is highly recommended to send all configuration objects that should be applied!

However there is possibility to omit individual configuration objects from request, for each omitted object in request fallback configuration value will be used :

Missing fieldwill use fallback values from
in filter_configurationdefault configuration of access controller
in stream_filter_configurationglobal filter_configuration of request
stream_groupsℹ️ Because we can not distinguish between empty array and missing field in proto message we will treat missing stream_groups as if empty array was provided!
stream_filter_configurationsℹ️ Because we can not distinguish between empty map and missing field in proto message we will treat missing stream_filter_configurations as if empty map was provided!
SetDefaultFiltersConfiguration

This method internally deletes “appsettings.FiltersConfiguration.json” file and reloads default configuration.

Request validation

When setting configuration, all properties are validated and validation errors are propagated in errors response array.

Error handling

Service methods requests can fail from either:

  • validation failure
  • internal server error

If any error occurred, service response messages contains success property which will be set to false and errors array will contain error messages with type of error that occurred.

Service proto file

AccessControllerConfigurationService

syntax = "proto3";
package innovatrics.smartface;

// Global filters configuration
message FilterConfiguration
{
	FaceOrderConfiguration face_order_configuration = 1;
	OpeningDebounceConfiguration opening_debounce_configuration = 2;
	BlockingDebounceConfiguration blocking_debounce_configuration = 3;
	ExclusiveCameraConfiguration exclusive_camera_configuration = 4;
	NotIdentifiedPersonConfiguration not_identified_person_configuration = 5;
	BlacklistConfiguration blacklists_configuration = 6;
	FaceMaskConfiguration face_mask_configuration = 7;
	IntentionalAccessConfiguration intentional_access_configuration = 8;
	StreamGroupsConfiguration stream_groups_configuration = 9;
	SpoofCheckConfiguration spoof_check_configuration = 10;
}

message StreamGroupsConfiguration
{
	bool enabled = 1;
	int32 group_opening_debounce_ms = 2;
}

// Stream specific filters configuration
message StreamSpecificFilterConfiguration
{
	FaceOrderConfiguration face_order_configuration = 1;
	OpeningDebounceConfiguration opening_debounce_configuration = 2;
	BlockingDebounceConfiguration blocking_debounce_configuration = 3;
	ExclusiveCameraConfiguration exclusive_camera_configuration = 4;
	NotIdentifiedPersonConfiguration not_identified_person_configuration = 5;
	BlacklistConfiguration blacklists_configuration = 6;
	FaceMaskConfiguration face_mask_configuration = 7;
	IntentionalAccessConfiguration intentional_access_configuration = 8;
	SpoofCheckConfiguration spoof_check_configuration = 9;
}

// Individual filter configuration messages
message FaceOrderConfiguration
{
	bool enabled = 1;
	int32 order = 2;
}

message OpeningDebounceConfiguration
{
	bool opening_debounce_enabled = 1;
	int32 opening_debounce_ms = 2;
}

message BlockingDebounceConfiguration
{
	bool blocking_debounce_enabled = 1;
	int32 blocking_debounce_ms = 2;
}

message ExclusiveCameraConfiguration
{
	bool enabled = 1;
	int32 exclusivity_ms = 2;
}

message NotIdentifiedPersonConfiguration
{
	bool enabled = 1;
	int32 roaming_limit_time_ms = 2;
}

message BlacklistConfiguration
{
	bool enabled = 1;
	repeated string blacklists = 2;
}

message FaceMaskConfiguration
{
	bool enabled = 1;
	int32 denying_debounce_ms = 2;
}

message IntentionalAccessConfiguration
{
	bool enabled = 1;
	reserved 2; // Deprecated double always_open_for_face_area_percent_larger_than = 2;
	reserved 3; // Deprecated double required_face_approaching_rate_percent = 3;
	google.protobuf.DoubleValue always_open_for_face_size_larger_than = 4; 
	google.protobuf.DoubleValue prediction_milliseconds = 5;
}


message SpoofRateLimitingConfiguration
{
	bool enabled = 1;
	int32 spoof_attempts_count = 2;
	int32 spoof_attempts_window_ms = 3;
	int32 blocking_time_increment_cooldown_ms = 4;
	int32 blocking_time_increment_ms = 5;
	int32 max_blocking_time_ms = 7;
}

message SpoofCheckConfiguration
{
	bool enabled = 1;
	int32 denying_debounce_ms = 2;
	SpoofRateLimitingConfiguration spoof_rate_limiting_configuration = 3;
}

message ExpressionConfiguration
{
	bool enabled = 1;
	string expression = 2;
}

// Service request messages/ response messages

message GetFiltersConfigurationRequest { }

message SetDefaultConfigurationRequest { }

message SetFiltersConfigurationRequest
{
	// If missing, service wil use current active filters configuration !
	// If there is missing configuration object in filter_configuration
	// configuration values from current active filter configuration values will be used as fallback
	FilterConfiguration filter_configuration = 1;

	// If missing, service wil treat this as empty array !
	repeated StreamGroup stream_groups = 2;

	// If missing, service wil treat this as empty map !
	// If there is missing configuration object in any stream_filter_configuration value
	// configuration values from filter_configuration will be used as fallback
	map<string, StreamSpecificFilterConfiguration> stream_filter_configurations = 3;
}

message GetFiltersConfigurationResponse
{
	FilterConfiguration filter_configuration = 1;
	repeated StreamGroup stream_groups = 2;
	map<string, StreamSpecificFilterConfiguration> stream_filter_configurations = 3;
}

message StreamGroup {
	string description = 1;
	repeated string stream_ids = 2;
}

// Service response messages
message SetConfigurationResponse
{
	bool success = 1;
	repeated SetConfigurationError Errors = 2;
}

enum ErrorType
{
	UNSPECIFIED = 0;
	VALIDATION = 1;
	SERVER_ERROR = 2;
}

message SetConfigurationError
{
	enum ErrorType {
		UNSPECIFIED = 0;
		VALIDATION = 1;
		SERVER_ERROR = 2;
	}

	ErrorType error_type = 1;
	string error_message = 2;
}

message SetDefaultConfigurationResponse
{
	bool success = 1;
	repeated SetDefaultConfigurationError Errors = 2;
}

message SetDefaultConfigurationError
{
	enum ErrorType {
		UNSPECIFIED = 0;
		SERVER_ERROR = 1;
	}

	ErrorType error_type = 1;
	string error_message = 2;
}

service AccessControllerConfigurationService
{
	// Gets the current active configuration used by access controller
	rpc GetFiltersConfiguration(GetFiltersConfigurationRequest) returns (GetFiltersConfigurationResponse);

	// Applies new configuration that should be used for access controller
	// When RPC call successfully returns, it is guaranteed that new configuration was already applied
	// This configuration will be used until SetDefaultFiltersConfiguration method will be called
	rpc SetFiltersConfiguration(SetFiltersConfigurationRequest) returns (SetConfigurationResponse);

	// Sets default filters configuration of access controller
	rpc SetDefaultFiltersConfiguration(SetDefaultConfigurationRequest) returns (SetDefaultConfigurationResponse);	
}