Keywords

1 Introduction

As modern software systems become increasingly complex, they are required to comply with a myriad of growingly intricate regulations. The ability to monitor and control such systems is an important, technically challenging task.

Runtime enforcement [58] tackles this problem by observing and controlling a target system under scrutiny (SuS), so that its actions, possibly modified, comply with a given policy. Runtime enforcement is performed by a component called enforcer, which observes the SuS and influences its behavior as permitted by the system model, e.g., by suppressing or causing SuS actions. Enforcement is thus an inherently online problem performed during the SuS’s execution. When time constraints are involved, enforcement is called real-time. This is a more difficult problem than runtime monitoring [8], where the SuS is only observed and policy violations are reported, but not prevented. Applications of runtime enforcement are manifold, ranging from safety protocols in industrial automation to regulatory compliance and it is closely related to the problem of controller synthesis [1, 56].

Policies can be decomposed into provisions and obligations [37]. Compliance with provisions depends on past and present SuS behavior, and it is sufficient for an enforcer to react to the current SuS action. Compliance with obligations, on the other hand, depends on future SuS behavior, requiring the enforcer to account for this behavior and proactively act [11] to prevent violations.

In existing approaches to proactive runtime enforcement [11], policies are typically propositional: they regard every system action as either true or false. In practice, however, actions are often parameterized with data values coming from an infinite domain, like strings or integers, and first-order policies are used to formulate dependencies between such actions’ parameters. To the best of our knowledge, no previous work supports proactive enforcement of first-order policies: Hublet et al.’s [39] enforcement is real-time, but not proactive; Aceto et al. [5] similarly support only the reactive runtime enforcement of first-order provisions.

In this paper, we propose an approach for proactively enforcing metric first-order temporal logic (MFOTL) [18] policies. Our approach features a realistic system model that supports proactive real-time enforcement in the nick of time [11, 12], i.e., the enforcer can act at least once per clock tick. Our model includes causable, suppressable, and only-observable SuS actions. Due to its proactivity, our enforcer supports an expressive MFOTL fragment with past and future operators.

Our enforcer is sound (modified SuS behavior complies with a given policy) for an enforceable MFOTL fragment (EMFOTL), and transparent (if SuS behavior is already policy-compliant, then it is not modified) for a fragment of EMFOTL. Our enforcer relies on the runtime monitoring tool WhyMon [49] as a backend. After reviewing MFOTL and WhyMon (Sect. 2) we describe our approach and evaluate the associated implementation. Our work makes the following contributions:

  • We introduce a new system model for the proactive real-time enforcement of metric first-order policies (Sect. 3).

  • We present an enforceable MFOTL fragment (called EMFOTL) with past and future operators that we characterize using a type system (Sect. 4).

  • We develop an enforcement algorithm for EMFOTL and prove its soundness. We also prove its transparency for a fragment of EMFOTL (Sect. 5).

  • We implement the type system and the algorithm into a new tool, called WhyEnf. We carry out a case study on monitoring core GDPR provisions [7], using WhyEnf to enforce the monitored policies. We find that WhyEnf can seamlessly enforce all monitorable policies from this case study in real time with modest runtime overhead (Sect. 6).

To our knowledge, WhyEnf (available at [43]) is the first proactive first-order policy enforcer (Sect. 7). All proofs can be found in our extended report [42].

2 Preliminaries

We introduce traces that model system executions, metric-first order temporal logic (MFOTL), and WhyMon, a monitor for an expressive MFOTL fragment.

Let \(x,y,z \in \mathbb {V}\) be variables and \(c, d \in \mathbb {D}\) be values from an infinite domain \(\mathbb {D}\) of constant symbols, like integers or strings. Terms \(t \in \mathbb {V}\cup \mathbb {D}\) are either variables or constants. Finite sequences of terms \(t_1, \ldots , t_n\) are written as \(\overline{t}\). Let \(\mathbb {E}\) denote a finite set of event names, and the function \(\iota : \mathbb {E}\rightarrow \mathbb {N}\) map event names to arities. An event is a pair \((e,(d_1,\dots ,d_{\iota (e)})) \in \mathbb {E}\times \mathbb {D}^{\iota (e)}\) of an event name e and \(\iota (e)\) arguments. We fix a signature \(\varSigma = (\mathbb {D}, \mathbb {E}, \iota )\) and define the set \(\mathbb{D}\mathbb{B}\) of databases over \(\varSigma \) as \(\mathcal {P}(\lbrace (e,\, \overline{d})\, \mid \, e \in \mathbb {E},\; \overline{d} \in \mathbb {D}^{\iota (e)}\rbrace ).\) The subset of all databases with event names in \(E \subseteq \mathbb {E}\) is \(\textsf{DB}(E) {:}{=}\lbrace D \in \mathbb{D}\mathbb{B}\mid \forall (e,(d_1,\dots ,d_{\iota (e)})) \in D.\ e \in E \rbrace \).

Example 1

Consider a system logging GDPR-relevant events defined with the signature \(\varSigma _0 = (\mathbb {N},\mathbb {E}_0,\iota _0)\), where \(\mathbb {E}_0=\{\textsf{use},\textsf{consent},\textsf{delete},\mathsf {deletion\_request}, \mathsf {legal\_ground}\}\), \(\iota _0(\textsf{use})=\iota _0(\textsf{delete})=\iota _0(\mathsf {deletion\_request})=3\), and \(\iota _0(\textsf{consent})=\iota _0(\mathsf {legal\_ground})=2\). The events’ denotations are: \(\textsf{use}(c,d,u)\) means ‘system uses user u’s data d from category c’, \(\textsf{delete}(c,d,u)\) means ‘user u’s data d from category c is deleted’, \(\mathsf {deletion\_request}(c,d,u)\) means ‘user u requests deletion of data d from category c’, \(\textsf{consent}(u,c)\) means ‘user u provides consent for category c’, and \(\mathsf {legal\_ground}(u,d)\) means ‘legal ground was claimed to process user u’s data d’.

A trace \(\sigma \) is a sequence \(\left\langle {(\tau _i,D_i)}\right\rangle _{0\le i \le k},~\hbox {k} \in \mathbb {N}\cup \lbrace \infty \rbrace \) of timestamps \(\tau _i \in \mathbb {N}\) and finite databases \(D_i \in \mathbb{D}\mathbb{B}\), where timestamps grow monotonically (\(\forall i < |\sigma |.~\tau _i \le \tau _{i+1}\)) and progress (if \(|\sigma | = \infty \), then \(\forall \tau .\; \exists i.\;\tau < \tau _i\)). An index \(0\le i<|\sigma |\), in a trace \(\sigma \) is called a time-point. The empty trace is denoted by \(\varepsilon \), the set of all traces by \(\mathbb {T}\), and the set of finite (resp. infinite) traces by \(\mathbb {T}_f\) (resp. \(\mathbb {T}_\omega \)). For traces \(\sigma \in \mathbb {T}_f\) and \(\sigma '\in \mathbb {T}\), \(\sigma \cdot \sigma '\) denotes their concatenation. A property is a subset \(P \subseteq \mathbb {T}_\omega \).

Example 2

Consider two infinite traces of a data management system

$$\begin{aligned} \sigma _1\! &=\! (10, \{ \textsf{consent}(1, 1), \textsf{consent}(1, 2)), (50, \{ \textsf{use}(1, 3, 1), \textsf{use}(2, 1, 1) \}), \dots \\ \sigma _2\! &=\! (10, \{ \mathsf {deletion\_request}(2, 1, 1)\}), (50, \{ \textsf{use}(1, 3, 1) \}), \dots \end{aligned}$$

In \(\sigma _1\), user 1 provides consent for categories 1 and 2 at time-point 0 with timestamp 10; at time-point 1 with timestamp 50, the system uses user 1’s data 3 (with category 1) and user 1’s data 1 (with category 2). In \(\sigma _2\), user 1 requests deletion of data 1 with category 2, and then the system uses data 3 with category 1.

MFOTL formulae are defined by the following grammar

figure a

where \(e\in \mathbb {E}\), \(x \in \mathbb {V}\), and \(I \in \mathbb {I}\) ranges over non-empty intervals in \(\mathbb {N}\). We use the standard abbreviations \(\bot {:}{=}\lnot \top \), \(\varphi \vee \psi {:}{=}\lnot (\lnot \varphi \wedge \lnot \psi )\), \(\varphi \rightarrow \psi {:}{=}\lnot \varphi \vee \psi \), \(\varphi \leftrightarrow \psi {:}{=}(\varphi \rightarrow \psi ) \wedge (\psi \rightarrow \varphi )\), \(\forall x.~\varphi {:}{=}\lnot (\exists x.~\lnot \varphi )\), \({\lozenge }_I \varphi {:}{=}\top {\textsf{U}}_I \varphi \) (eventually), \({\blacklozenge }_I \varphi {:}{=}\top {\textsf{S}}_I \varphi \) (once), \({\square }_I \varphi {:}{=}\lnot {\lozenge }_I \lnot \varphi \) (always), and \({\blacksquare }_I \varphi {:}{=}\lnot {\blacklozenge }_I \lnot \varphi \) (historically). A polarity \(p \in \{+,-\}\) acts upon a formula \(\varphi \) by \(+\varphi {:}{=}\varphi \) and \(-\varphi {:}{=}\lnot \varphi \). We omit intervals of the form \([0,\infty )\) from the temporal operators’ subscript. We write \(\varphi [d/x]\) for the formula resulting from substituting the free variable x with the constant d in the formula \(\varphi \). The notation \(\varphi [v]\) generalizes such a unary substitution to applying a full valuation \(v : \mathbb {V}\rightarrow \mathbb {D}\), i.e., a mapping from variables to domain values.

Example 3

Suppose that the time unit is days. Consider the formulae

$$\begin{aligned} \varphi _{\textsf{law}} &\equiv {\square }\left( \forall c, d, u.\,\textsf{use}\left( c, d, u\right) \rightarrow {\blacklozenge }\left( \textsf{consent}\left( u, c\right) \vee \mathsf {legal\_grounds}\left( u, d\right) \right) \right) \\ \varphi _{\textsf{del}} &\equiv {\square }\left( \forall c, d, u.\,\mathsf {deletion\_request}\left( c, d, u\right) \rightarrow {\lozenge }_{[0,30]}\textsf{delete}\left( c, d, u\right) \right) \end{aligned}$$
Fig. 1.
figure 1

MFOTL semantics for a fixed, infinite trace \(\sigma \)

The formula \(\varphi _{\textsf{law}}\) formalizes lawfulness of processing: ‘whenever data d with category c belonging to user u is processed, then either u has consented to her data with category c being used, or the controller has claimed a legal ground to process d.’ The formula \(\varphi _{\textsf{del}}\) formalizes the GDPR’s right to erasure: ‘whenever a user u requests the deletion of data d of category c, then d must be deleted within 30 d’.

We write \(\textsf{fv}(\varphi )\) and \(\textsf{cs}(\varphi )\) for the set of free variables and constants of a formula \(\varphi \), respectively. We define the active domain \(\textsf{AD}_{i}(\varphi )\) of a formula \(\varphi \) at time-point i as \(\textsf{cs}(\varphi ) \cup \left( \bigcup \nolimits _{j\le i}\{d\mid d \text { is one of } d_k \text { in } e(d_1,\dots ,d_{\iota (e)})\in D_j\}\right) \). The active domain of \(\varphi \) at i contains all constants occurring in \(\varphi \) together with all constants occurring as event arguments in the trace up to time-point i.

Example 4

As \(\textsf{cs}(\varphi _\textsf{law})\!=\!\textsf{cs}(\varphi _\textsf{del})\!=\!\emptyset \), we have \(\textsf{AD}_{0}(\varphi _\textsf{law})\!=\!\textsf{AD}_{0}(\varphi _\textsf{del})\!=\!\{1,2\}\) and \(\textsf{AD}_{1}(\varphi _\textsf{law})\!=\!\textsf{AD}_{1}(\varphi _\textsf{del})\!=\!\{1,2,3\}\) for \(\sigma _1\).

MFOTL’s semantics (Fig. 1) is defined over infinite traces. Given a valuation v, we define the interpretation of terms as \(\llbracket \, x \,\rrbracket _{v}=v(x)\) (for variables) and \(\llbracket \, c \,\rrbracket _{v}=c\) (for constants). We lift this operation straightforwardly to lists of terms. A valuation update is denoted as v[d/x]. Each sequent \(v, i \vDash _\sigma \varphi \) denotes that \(\varphi \) is satisfied at time-point i of trace \(\sigma \) under valuation v. We omit \(\sigma \) whenever it is clear from the context. The language of a formula \(\varphi \) is \(\mathcal {L}(\varphi ) = \lbrace \sigma \in \mathbb {T}_\omega \mid \exists v.~v, 0 \vDash _\sigma \varphi \rbrace \).

Lima et al. [49] present an algorithm and a tool, called WhyMon, that can monitor an expressive safety fragment of MFOTL both online and offline. This fragment contains all formulae with future-bounded until operators. Thus, it strictly extends the fragments supported by other tools like MonPoly [13] and VeriMon [9], which only support formulas in relational algebra normal form [20], and DejaVu [35], which is restricted to past temporal operators.

Abstractly, WhyMon implements a function \(\textsc {Sat}(v, \varphi ,i)= v, i \vDash \varphi \) that checks if a valuation satisfies the formula \(\varphi \) on a (fixed) trace \(\sigma \) at time-point i. Internally, it manipulates objects representing proofs of \(\varphi \)’s subformulae. This technique additionally allows WhyMon to output explanations [48] of its verdicts (satisfactions or violations) in the form of proofs that can be checked using a proof checker. We refer to Lima et al.’s work [49] for further details.

3 Proactive, Real-Time, First-Order Enforcement

Our system model (Sect. 3.1) is inspired by Basin et al.’s model for proactive propositional enforcement [11, 12] and Hublet et al.’s model for (non-proactive) first-order enforcement [39]. Within this model, we define enforcers (Sect. 3.2).

Fig. 2.
figure 2

System model for proactive real-time first-order enforcement

3.1 System Model

Figure 2 shows a system S supervised by an enforcer E described using a communication diagram [32]. The system S interacts with an environment X that E cannot control. The enforcer E must ensure that the sequence of actions executed by S complies with a given policy P. To this end, S reports to E sets of events (from \(\mathbb {E}\)) that capture the system’s observable actions. The enforcer E can send commands to S, whereby it instructs S to cause or suppress the actions corresponding to specific events. There are two kinds of such commands, \(\textsf{R}\)-commands and \(\textsf{P}\)-commands, which will be described below. We assume that the set of events is partitioned into a set of causable events \({\mathbb {C}}\) capturing actions that E can instruct S to cause, a set of suppressable events \({\mathbb {S}}\) capturing actions that E can instruct S to suppress, and a set of only-observable events \({\mathbb {O}}= \mathbb {E}\setminus ({\mathbb {S}}\cup {\mathbb {C}})\) capturing actions that can be neither caused nor suppressed.

Example 5

Suppose that the system from Example 1 can be instrumented so that an enforcer can (observe and) prevent data usage and cause data deletion, but can only observe the remaining actions. The corresponding event sets are then \({\mathbb {C}}\!=\!\{\textsf{delete}\}\), \({\mathbb {S}}\!=\!\{\textsf{use}\}\), and \({\mathbb {O}}\!=\!\{\textsf{consent},\mathsf {legal\_ground},\mathsf {deletion\_request}\}\).

More specifically, we assume that E interacts with S in three modes: (1) Before performing any suppressable actions, S sends the corresponding set of (suppressable) events \(D \in \mathbb{D}\mathbb{B}\) to E. The enforcer inspects D and reactively responds with an \(\textsf{R}\)-command \(\textsf{RCom}(D_{\mathbb {C}}, D_{\mathbb {S}})\), where \(D_{\mathbb {C}}\in \textsf{DB}({\mathbb {C}})\) is a set of causable events and \(D \supseteq D_{\mathbb {S}}\in \textsf{DB}({\mathbb {S}})\) is a set of suppressable events. S then performs the actions corresponding to the events in \((D \setminus D_{\mathbb {S}}) \cup D_{\mathbb {C}}\), i.e., all actions corresponding to events in \(D_{\mathbb {C}}\) (resp. \(D_{\mathbb {S}}\)) are caused (resp. suppressed). (2) After performing actions that are not suppressable, S sends the corresponding set of events \(D \in \mathbb{D}\mathbb{B}\) to E. The enforcer inspects D and responds with an \(\textsf{R}\)-command \(\textsf{RCom}(D_{\mathbb {C}}, \emptyset )\). As no suppressable actions are to be performed and the events are sent after the actions, the enforcer can only instruct S to cause actions, but not to suppress them. (3) Before any clock tick (‘in the nick of time’ [12]), E can proactively send a \(\textsf{P}\)-command \(\textsf{PCom}(D_{\mathbb {C}})\) with \(D_{\mathbb {C}}\in \textsf{DB}({\mathbb {C}})\) to S. The system S then performs the actions corresponding to the events in \(D_{\mathbb {C}}\). Note that sending a \(\textsf{P}\)-command before a tick is always possible, but the enforcer may instead choose not to send any command.

These modes of interaction cover different enforcement scenarios. In mode (1), E reacts to suppressable events by possibly suppressing or causing events. E.g., the formula \(\varphi _\textsf{law}\) from Example 3 can be enforced by suppressing data usage (the \(\textsf{use}\) events) if no appropriate event has previously occurred. In mode (2), E reacts to only-observable events (e.g., the \(\textsf{consent}\) events) by possibly causing events corresponding to corrective actions after the executed action. Finally, mode (3) enforces policies by causing events at times when the SuS does not, on its own, send any observable events. This is the case, e.g., when enforcing \(\varphi _\textsf{del}\) on \(\sigma _2\): data 1 with category 2 must be deleted between timestamps 10 and 40.

Discussion. Assume that the enforcer E can ensure that the sequence of actions it observes complies with P. When does this guarantee that the system actually complies with P? Basin et al. [12] state two conditions for achieving soundness: (a) the system and enforcer must be synchronized and (b) the enforcer must be fast enough to keep up with the real-time system behavior. These conditions also apply in our model. Condition (a) ensures that the order of events observed by E reflect the order of S’s actions. Condition (b) ensures that the timestamps of events reflect the time at which the corresponding actions are performed by S. The interval t between two clock ticks must satisfy the real-time condition \(t > \delta _{S} + 2\delta _{S\leftrightarrow E} + \delta _E\), where \(\delta _{S}\) is the worst-case time needed by S to create events before performing observable actions and process the enforcer’s reactions, \(\delta _{S\leftrightarrow E}\) is the worst-case communication time between S and E, and \(\delta _E\) is the worst-case latency of the enforcer. Threats to the model’s validity may thus stem from high communication time, or poor SuS or enforcer performance.

3.2 Enforcers

An enforcer reads the consecutive prefixes of an SuS’s trace and returns commands:

Definition 1

A command is any element of the form \(\textsf{RCom}(D_{\mathbb {C}},D_{\mathbb {S}})\) (‘\(\textsf{R}\)-command’), \(\textsf{PCom}(D_{\mathbb {C}})\) (‘\(\textsf{P}\)-command’), or \(\textsf{NoCom}\) (‘no command’), where \(D_{\mathbb {C}}\in \textsf{DB}({\mathbb {C}})\) and \(D_{\mathbb {S}}\in \textsf{DB}({\mathbb {S}})\). The set of commands is denoted by \(\mathcal {C}\).

Definition 2

An enforcer \(\mathcal {E}\) is a triple \((\mathcal {S},s_0,\mu )\), where \(\mathcal {S}\) is a set of states, \(s_0 \in \mathcal {S}\) is an initial state, and \(\mu : \mathbb {T}_f \times \mathcal {S} \times (\mathbb {N}\cup \{ \bot \}) \rightarrow \mathcal {C}\times \mathcal {S}\) is a computable update function such that the following two conditions hold:

$$\begin{aligned} \forall \sigma , \tau ,D,s.~\exists D_{\mathbb {C}},D_{\mathbb {S}},s'.~\mu (\sigma \cdot (\tau ,D),s,\bot ) &= (\textsf{RCom}(D_{\mathbb {C}},D_{\mathbb {S}}), s') \wedge D_{\mathbb {S}}\subseteq D\\ \forall \sigma , s, \tau \in \mathbb {N}.~\exists D_{\mathbb {C}}, s'.~\mu (\sigma ,s,\tau ) &\in \{(\textsf{PCom}(D_{\mathbb {C}}), s'), (\textsf{NoCom},s')\}. \end{aligned}$$

If \(\mu \)’s third argument is \(\bot \), then \(\mu \) returns an \(\textsf{R}\)-command. The set of events to be suppressed contained in this command is a subset of the last set of events reported by the SuS. On the other hand, if \(\mu \)’s third argument is an integer timestamp, then \(\mu \) returns either a \(\textsf{P}\)-command for the corresponding timestamp, or no command. Any enforcer induces the following trace transduction:

Definition 3

For any \(\sigma \in \mathbb {T}\) and enforcer \(\mathcal {E}=(\mathcal {S},s_0,\mu )\), the enforced trace \(\mathcal {E}(\sigma )\) is defined co-recursively in Algorithm 1, where \(\textsf{fts}(\sigma )\) is the first timestamp in \(\sigma \).

Algorithm 1 formalizes the interaction described in Sect. 3.1: the enforcer is called once at every time-point in the input trace \(\sigma \) to generate an \(\textsf{R}\)-command (lines 6–7), and once before each clock tick to (possibly) generate a \(\textsf{P}\)-command (lines 3–5). The generated commands are executed sequentially to produce the enforced trace \(\mathcal {E}(\sigma )\), which thus reflects the actions performed by the SuS when composed with the enforcer as in Sect. 3.1.

figure b

To be considered correct with respect to a given property P, enforcers are typically required to fulfill two properties: soundness and transparency [47]. Soundness states that any trace modified by the enforcer must be compliant with P, while transparency states that the enforcer does not alter a trace that already complies with the policy. A transparent enforcer modifies the system’s behavior only when necessary. The following definition formalizes these notions.

Definition 4

An enforcer \(\mathcal {E}\) is sound with respect to a property P iff for any \(\sigma \in \mathbb {T}_\omega \), we have \(\mathcal {E}(\sigma ) \in P\). An enforcer \(\mathcal {E}=(\mathcal {S},s_0,\mu )\) is transparent with respect to a property P iff for all \(\sigma \in P\), \(\mathcal {E}(\sigma ) = \sigma \). A property P (resp. a formula \(\varphi \)) is enforceable iff there exists a sound enforcer with respect to P (resp. \(\mathcal {L}(\varphi )\)).

4 Enforceable MFOTL Formulae

In this section, we present EMFOTL, an expressive and enforceable fragment of MFOTL. An enforcer for EMFOTL formulae will be presented in Sect. 5.

EMFOTL is defined using the typing rules in Fig. 3. These consist of sequents of the form \(\varGamma \vdash \varphi : \alpha \), reading ‘\(\varphi \) types to \(\alpha \) under \(\varGamma \)’. Here, context \(\varGamma : \mathbb {E}\rightarrow \lbrace {\mathbb {C}},{\mathbb {S}}\rbrace \) is a mapping from event names to either of the symbols \({\mathbb {C}}\) or \({\mathbb {S}}\), \(\varphi \) is an MFOTL formula, and \(\alpha \) is a type in \(\{{\mathbb {C}},{\mathbb {S}}\}\). The type names \({\mathbb {C}}\) and \({\mathbb {S}}\) overload the names of the sets of suppressable and causable events in a natural way: any event \(e_c(\overline{t})\) with \(e_c \in {\mathbb {C}}\) (resp. \(e_s \in {\mathbb {S}}\)) has type \({\mathbb {C}}\) (resp. \({\mathbb {S}}\)) under the context \(\{e_c \mapsto {\mathbb {C}}\}\) (resp. \(\{e_s \mapsto {\mathbb {S}}\}\)). EMFOTL is defined as the set of all \(\varphi \) for which \(\exists \varGamma .\,\varGamma \vdash \varphi : {\mathbb {C}}\). Intuitively, a formula types to \({\mathbb {C}}\) under \(\varGamma \) (‘\(\varphi \) is causable under \(\varGamma \)’) if it can be enforced by causing events \(e_c(\overline{t})\) such that \(\varGamma (e_c)={\mathbb {C}}\) and suppressing events \(e_s(\overline{t})\) such that \(\varGamma (e_s)={\mathbb {S}}\). It types to \({\mathbb {S}}\) under \(\varGamma \) (‘\(\varphi \) is suppressable under \(\varGamma \)’) if \(\lnot \varphi \) can be enforced under the same conditions on \(\varGamma \).

Fig. 3.
figure 3

Typing rules for EMFOTL

Fig. 4.
figure 4

Enforcement for temporal operators: = cause \(\varphi \) and = suppress \(\varphi \)

We now review the typing rules presented in Fig. 3. Our approach for enforcing temporal operators is illustrated in Fig. 4.

Constants and predicates (Rules \(\top ^{\mathbb {C}}\), \(\bot ^{\mathbb {S}}\), \(\mathbb {E}^{\mathbb {C}}\), \(\mathbb {E}^{\mathbb {S}}\)). The constant \(\top \) (resp. \(\bot \)) is causable (resp. suppressable). Event \(e(t_1,\dots ,t_k)\) is causable (resp. suppressable) under \(\varGamma \) if \(e \in {\mathbb {C}}\) and \(\varGamma (e)={\mathbb {C}}\) (resp. \(e \in {\mathbb {S}}\) and \(\varGamma (e)={\mathbb {S}}\)).

Negation (Rules \({\lnot }^{\mathbb {C}}\), \({\lnot }^{\mathbb {S}}\)). Negation exchanges \({\mathbb {C}}\) and \({\mathbb {S}}\): a formula is causable iff its negation is suppressable; it is suppressable iff its negation is causable.

Conjunction (Rules \({\wedge }^{\mathbb {C}}\), \({\wedge }^{{\mathbb {S}}\textsc {L}}\), \({\wedge }^{{\mathbb {S}}\textsc {R}}\)). A conjunction is causable if both of its conjuncts are causable; it is suppressable if either of its conjuncts is suppressable.

Quantifiers (Rules \({\exists }^{\mathbb {C}}\), \({\exists }^{\mathbb {S}}\)). The formula \(\varphi '=\exists x.~\varphi \) is causable if \(\varphi \) is causable: it is enough to set x to some value v and cause \(\varphi [x/v]\) to cause \(\varphi '\). In contrast, to suppress \(\varphi '\) at i, we must ensure that no value of \(v \in \mathbb {D}\) can satisfy \(\varphi \). If \(\varphi \) depends on the future, then values of v satisfying \(\varphi '\) may only be discovered strictly after i. Then, it may not be possible to decide which \(\varphi [x/v]\) to suppress at i. Our fragment rules this case out by requiring that x be past-guarded in \(\varphi \), i.e., that any value of x that satisfies \(\varphi \) is a constant or present in the trace up until i. Formally:

Definition 5

(Past-guardedness). A variable x is past-guarded in \(\varphi \) iff

\(\forall v,i.~v, i \vDash \varphi \wedge x \in \textrm{dom}\,v \Longrightarrow v(x) \in \textsf{AD}_{i}(\varphi )\).

Past-guardedness can be soundly overapproximated using the type system in the upper half of Fig. 3. The PG typing rules define sequents of the form \(\vdash \varphi : \textsf{PG}(x)^p\), where \(p \in \{+,-\}\). In our extended report [42], we prove

Lemma 1

For \(p \in \{+,-\}\), if \(\vdash \varphi : \textsf{PG}(x)^p\), then x is past-guarded in \(p \varphi \).

  • Since (Rules \({\textsf{S}}^{\mathbb {C}}\), \({\textsf{S}}^{{\mathbb {S}}\textsc {L}}\), \({\textsf{S}}^{{\mathbb {S}}\textsc {LR}}\)). As enforcers cannot affect the past, causation of \(\varphi ' = \varphi {\textsf{S}}_I \psi \) is only possible when \(0 \in I\) and \(\psi \) is enforceable. In this case, \(\varphi '\) is caused by causing \(\psi \) in the present (Fig. 4, a). To suppress \(\varphi '\), we consider two scenarios. If \(0 \notin I\), then to suppress \(\varphi '\), it suffices to suppress \(\varphi \) in the present (Fig. 4, b). If \(0 \in I\), both \(\varphi \) and \(\psi \) may need to be suppressed (Fig. 4, c).

  • Until (Rules \({\textsf{U}}^{\mathbb {S}}\), \({\textsf{U}}^{{\mathbb {C}}\textsc {R}}\), \({\textsf{U}}^{{\mathbb {C}}\textsc {LR}}\)). The formula \(\varphi '=\varphi {\textsf{U}}_I \psi \) is causable if both \(\varphi \) and \(\psi \) are causable: one can cause \(\varphi \) until the interval I has elapsed, and then cause \(\psi \) ‘in the nick of time’ (Fig. 4, d). This requires a finite upper bound for I; otherwise, the enforcer may wait indefinitely to cause \(\psi \), producing a non-compliant trace. (For \(I = [a,\infty )\), we could enforce \(\varphi '\) non-transparently by causing \(\psi \) after an arbitrary, finite interval [ab). In this case, the user could have as well specified \(\varphi {\textsf{U}}_{[a,b)} \psi \). Hence, our type system requires a finite I.) Alternatively, if \(0 \in I\), then \(\varphi '\) can be caused when \(\psi \) is causable, with the enforcer causing \(\psi \) as soon as \(\varphi \) ceases to hold or the interval has elapsed (Fig. 4, e). In contrast, \(\varphi '\) can be suppressed whenever \(\psi \) is suppressable (Fig. 4, f). This also applies when I is unbounded: if necessary, the formula \(\psi \) can be suppressed indefinitely. Enforcement can thus be performed for formulae that are generally not supported by existing monitors [18]. Namely, monitors exclude non-future-bounded formulae, for which compliance cannot be guaranteed by observing a finite prefix of the trace and hence verdicts cannot be given in finite time. However, an enforcer can ensure compliance at every time-point.

  • Previous. The formula \(\varphi '=\mathop {\CIRCLE }\nolimits _I \varphi \) can neither be caused nor suppressed without editing databases of events that happened strictly in the past. This goes beyond the enforcer’s capabilities in our model.

  • Next (Rules \(\mathop {\Circle }\nolimits ^{\mathbb {C}}\), \(\mathop {\Circle }\nolimits ^{\mathbb {S}}\)). If \(\varphi \) is suppressable, the formula \(\varphi '=\mathop {\Circle }\nolimits _I \varphi \) is also suppressable: \(\varphi '\) is suppressed by suppressing \(\varphi \) at the next time-point (Fig. 4, g). In contrast, causing \(\varphi '\) is not possible for arbitrary I. If \(I=[a,b)\) with \(a > 0\), then, to cause \(\varphi '\) at i, one must ensure \(\tau _{i+1} \ge \tau _i +a\). But the next time-point in the input trace might be \(\tau _{i+1} < \tau _i+a\) (e.g., \(\tau _{i+1} =\tau _i\)), and this timestamp cannot be suppressed. If \(I = [0,0]\), then enforcing \(\varphi ''={\square }\varphi '\) is not possible, since no trace satisfies \(\varphi ''\) (a trace must satisfy progress): one cannot both support \(I = [0,0]\) in rule \(\mathop {\Circle }\nolimits ^{\mathbb {C}}\) and use the previous definition of \({\textsf{U}}^{\mathbb {S}}\). Therefore, our fragment only supports causation of \(\mathop {\Circle }\nolimits _I \varphi \) for intervals I of the form [0, b), \(b > 0\) (Fig. 4, h).

Our use of the context \(\varGamma \) is inspired by Hublet et al. [39]. By ensuring that all events with the same name are only caused or only suppressed, we exclude non-enforceable formulae such as \(e \wedge \lnot e\), where e is both causable and suppressable.

Example 6

We show that \(\varphi _\textsf{del}\) presented in Example 3 is in EMFOTL. We work with the “desugared” variant of \(\varphi _\textsf{del}\) (instead of using abbreviations like \({\lozenge }\)):

$$\begin{aligned} \varphi _\textsf{del}' \equiv \lnot \left( \top {\textsf{U}}\left( \exists c, d, u.\,\mathsf {deletion\_request}\left( c, d, u\right) \wedge \left( \lnot \left( \top {\textsf{U}}_{[0,30]} \textsf{delete}\left( c, d, u\right) \right) \right) \right) \right) \end{aligned}$$

Furthermore, we shorten \(\varphi _\textsf{del}' \equiv \lnot (\top {\textsf{U}}\varphi _{\exists _1})\), where:

$$\begin{aligned}\begin{gathered} \varphi _{\exists _1} \equiv \exists c.\,\varphi _{\exists _2} \qquad \varphi _{\exists _2} \equiv \exists d.\,\varphi _{\exists _3} \qquad \varphi _{\exists _3} \equiv \exists u.\,\varphi _{\wedge } \qquad \varphi _{\wedge } \equiv \varphi _{\wedge _1} \wedge \varphi _{\wedge _2} \\ \varphi _{\wedge _1} \equiv \mathsf {deletion\_request}\left( c, d, u\right) \qquad \varphi _{\wedge _2} \equiv \lnot \varphi _{{\textsf{U}}} \qquad \varphi _{{\textsf{U}}} \equiv \top {\textsf{U}}_{[0,30]} \textsf{delete}\left( c, d, u\right) \end{gathered}\end{aligned}$$

Lastly, we use the typing rules presented in Fig. 3 to show that \(\varphi _{\textsf{del}}'\) types to \({\mathbb {C}}\):

figure e

where \(P_{1,2,3}\) respectively stand for:

figure f
figure g

The formula \(\varphi _\textsf{law}\) is also in EMFOTL (see  our extended report [42]).

5 Enforcing EMFOTL

We now describe our enforcement algorithm. First, we present the enforcer’s state, which consists of a set of obligations (Sect. 5.1). We then explain how Lima et al.’s monitoring algorithm [49] can be extended to check the satisfaction of a formula \(\varphi \) under assumptions about the future (Sect. 5.2). Finally, we present our algorithm (Sect. 5.3) and prove its soundness and transparency (Sect. 5.4).

5.1 Obligations

Our algorithm manipulates sets of obligations that encode the formulae to be caused or suppressed in the future. There are two types of obligations, present and future obligations. A present obligation is a triple \((\varphi ,v,p)\)  of an MFOTL formula \(\varphi \), a valuation v, and a polarity \(p \in \{+,-\}\) such that \(p\varphi \in \text {EMFOTL}{}\). After reading a new time-point, our enforcer’s state will contain a finite set of such present obligations. Some of these obligations will be immediately discharged via causation or suppression. Others will be processed to generate simpler present obligations and new future obligations that will then be propagated to the next time-point. Future obligations are triples \((\xi ,v,p)\) where \(\xi : \mathbb {N}\rightarrow \text {MFOTL}\) maps timestamps to EMFOTL formulae and v and p are as before. The set of future obligations is denoted by \(\textsf{FO}\). The mapping \(\xi \) is evaluated with the next timestamp to generate present obligations at the next time-point in the trace.

In some cases (e.g., \(\varphi _\textsf{del}\)), the enforcer must insert a time-point. In other cases (e.g., \(\varphi _\textsf{law}\)), the enforcer can modify the events at existing time-points. To insert a time-point only when necessary, we use a special, causable \(\texttt{TP}\) event encoding the existence of a time-point. When processing a time-point already present in the trace (l. 6 in Algorithm 1), the enforcer receives the additional present obligation \((\texttt{TP},\emptyset ,+)\), as the time-point cannot be suppressed. When computing \(\textsf{P}\)-commands (l. 3 in Algorithm 1), this obligation is not given to the enforcer, but \(\texttt{TP}\) may be generated from other obligations, in which case a time-point is inserted.

Figure 5 shows the mappings used in the first component of future obligations. There are three types of mappings, corresponding to the obligations passed to the enforcer in the initial state and those generated from unrolling \(\mathop {\Circle }\nolimits \) and \({\textsf{U}}\).

Fig. 5.
figure 5

Mappings in the first component of future obligations

5.2 Checking Satisfaction of MFOTL Formulae Under Assumptions

Our enforcer uses WhyMon’s monitoring algorithm to check the satisfaction of formulae. Unlike Lima et al. [49], we must however compute satisfactions under assumptions encoding future obligations. To guarantee, e.g., that causing \(\varphi \) in the present and satisfying \( fo =(\lambda \tau '.\,\top {\textsf{U}}(\texttt{TP}\wedge \lnot \varphi ),\emptyset ,-)\) guarantees \({\square }\varphi \), one must be able to check that after causing \(\varphi \), \({\square }\varphi \) is satisfied at i assuming that \( fo \) is satisfied at \(i+1\). Since the enforcer will suppress all time-points not containing \(\texttt{TP}\), future time-points can be assumed to all contain \(\texttt{TP}\).

Let \(\{{\mathbb {C}}\}_+ := {\mathbb {C}}\), \(\{{\mathbb {C}}\}_- := {\mathbb {S}}\), and \(\overline{\sigma }^\texttt{TP}=\left\langle {(\tau _i,D_i \cup \lbrace \texttt{TP}\rbrace )}\right\rangle _{i \in \mathbb {N}}\) for the trace \(\sigma = \left\langle {(\tau _i,D_i)}\right\rangle _{i \in \mathbb {N}}\). Consider \(\varphi \in \text {EMFOTL}{}\), and obtain \(\varGamma \) such that \(\varGamma \vdash \varphi : {\mathbb {C}}\). Our satisfiability checker under assumptions is a function

$$\textsc {Sat}: (\mathbb {V}\rightarrow \mathbb {D}) \times \text {MFOTL}{} \times \mathbb {T}_f \times \mathcal {P}(\textsf{FO}) \rightarrow \{\top ,\bot \}$$

. The implementation of the checker must ensure that, for any \(p \in \{+,-\}\), \(\varphi \) such that \(\varGamma \vdash \varphi : \{{\mathbb {C}}\}_p\), and \(X \subseteq \textsf{FO}\), \(\textsc {Sat}(v, \varphi ,\sigma ',X)\) implies

$$\begin{aligned} & \forall ts \in \mathbb {N}, D \in \mathbb{D}\mathbb{B}, \sigma ''\in \mathbb {T}_\omega .~(\forall (\xi ,v',p') \in X.~v', |\sigma '| \vDash _{\sigma ' \cdot \overline{(ts,D) \cdot \sigma ''}^\texttt{TP}} p'\xi (ts))\\ &\qquad \qquad \qquad \qquad \qquad \qquad ~~\Longrightarrow v, |\sigma '|-1 \vDash _{\sigma '\cdot \overline{(ts,D) \cdot \sigma ''}^\texttt{TP}} \varphi .\qquad (\star ) \end{aligned}$$

Intuitively, this condition expresses that whenever \(\textsc {Sat}(v, \varphi , \sigma ', X)\) is true and the (infinite) trace \(\sigma =\sigma '\cdot \overline{(ts,D) \cdot \sigma ''}^\texttt{TP}\) satisfies all the future obligations in X at time-point \(|\sigma '|\), then \(\varphi \) holds over \(\sigma \) at time-point \(|\sigma '|-1\).

For our algorithm to eventually recognize satisfaction and terminate, one must ensure that for large enough X, the implication \((\star )\) is an equivalence. This guarantees that after generating a finite set of reactions and future obligations, the algorithm can use \(\textsc {Sat}\) to assess that no more immediate actions are needed.

Fig. 6.
figure 6

Additional proof rules

To support assumptions about the future, we extend Lima et al’s algorithm [49] with the proof rules in Fig. 6. In our extended report [42], we show

Lemma 2

The proof system of [49] extended with the rules from Fig. 6 yields a decision procedure \(\textsc {Sat}\) that satisfies (\(\star \)).

Lemma 3

There exists a set \(\textsf{FO}^+_{i,ts}(\varphi )\) such that whenever \(X \supseteq \textsf{FO}^+_{|\sigma |,\tau _{|\sigma |}}(\varphi )\), the converse of (\(\star \)) also holds for \(\textsc {Sat}\) constructed as in Lemma 2.

5.3 The Enforcement Algorithm

Our enforcer’s update function \(\textsf{enf}\) is shown in Algorithm 2. It is used to define an enforcer \(\mathcal {E}_\varphi =(\mathcal {S},s_\varphi ,\textsf{enf})\), where \(\mathcal {S}=\mathcal {P}(\textsf{FO})\) and \(s_\varphi = \lbrace (\textsf{fo}_{\textsf{init},\varphi },\emptyset ,+)\rbrace \). In the algorithm and its description below, we annotate operators that fulfill the typing conditions in Fig. 3 with the respective typing rule names. For example, we write \(\varphi {\textsf{U}}_{[a,b]}^{{\mathbb {C}}\textsc {LR}} \psi \) to denote \(\varphi {\textsf{U}}_{[a,b]} \psi \) where \(b \ne \infty \), \(\varGamma \vdash \varphi : {\mathbb {C}}\), and \(\varGamma \vdash \psi : {\mathbb {C}}\) under some \(\varGamma \).

As required by Definition 2, the function \(\textsf{enf}\) takes a trace \(\sigma \), a set of future obligations X, and a timestamp ts as input. If \(ts = \bot \), i.e., the enforcer processes a time-point already present in the trace, then ts is set to the latest timestamp \(\tau _{|\tau |}\) (line 4). The enforcer computes a (closed) formula \(\varPhi \) that summarizes all obligations at the present time-point (line 5). Then \(\varPhi \), \(\sigma \), an empty set of future obligations, and an empty valuation are passed to \(\textsf{enf}^+_{ts,\bot }\) (line 6). The function \(\textsf{enf}^+_{ts,b}\) takes a formula \(\varphi \), a trace \(\sigma \), a set of (new) future obligations X, and a valuation v as input, and returns a triple \((D_C,D_S,X')\) such that \(D_C\) is a set of events to cause, \(D_S\) is a set of events to suppress, and \(X'\) is an updated version of X. The function is parameterized by the current timestamp ts and a Boolean b that is true iff the current time-point is the last one with the current timestamp. The definition of \(\textsf{enf}^+\) (resp. \(\textsf{enf}^-\)) guarantees that if we update \(D_i\) according to \(D_S\) and \(D_C\) and assume that all obligations in \(X'\) are satisfied at time-point \(i+1\), then \(\varphi \) is always (resp. never) satisfied under v at i on the new trace.

After computing \(D_S\), \(D_C\), and \(X'\), an \(\textsf{R}\)-command \(\textsf{RCom}(D_C,D_S)\) is returned (line 7) and the state is updated to \(X'\). If \(ts \ne \bot \), a similar approach is followed, but now \(\texttt{TP}\) is not conjoined with \(\varPhi \) (line 9) and the boolean b is set to \(\top \) as enforcement happens ‘in the nick of time.’ If \(\texttt{TP}\) is part of the set \(D_C\) returned by \(\textsf{enf}^+\), then a \(\textsf{P}\)-command \(\textsf{PCom}(D_C)\) and a new state \(X'\) are returned. Otherwise, \(\textsf{NoCom}\) is returned and the state is not updated.

The functions \(\textsf{enf}^+\) and \(\textsf{enf}^-\) recurse over the structure of \(\varphi \). The traversal of \(\varphi \) is guided by the typing: the function \(\textsf{enf}^+\) (resp. \(\textsf{enf}^-\)) is only called on subformulae of type \({\mathbb {C}}\) (resp. \({\mathbb {S}}\)). The algorithm implements the approach described in Sect. 4. For space reasons, we only explain the more complex cases: \(\varphi = \varphi _1\wedge ^{\mathbb {C}}\varphi _2\), \(\varphi = \exists ^{\mathbb {S}}x.~\varphi _1\), and \(\varphi = \varphi _1 {\textsf{U}}_I^{{\mathbb {C}}\textsc {LR}} \varphi _2\).

  • Causing \(\varphi _1 \wedge \varphi _2\) (Algorithm 2, \(\textsf{enf}^+\) l. 9). Causing \(\varphi _1 \wedge \varphi _2\) where both \(\varphi _1\) and \(\varphi _2\) are causable requires a fixed-point computation [39]. Consider, e.g., the EMFOTL formula \(\varphi =\psi \wedge (\psi \rightarrow \chi )\), where \(\psi \) and \(\chi \) both type to \({\mathbb {C}}\). If neither \(\psi \) nor \(\chi \) are satisfied, then the right conjunct of \(\varphi \) is satisfied; however, to satisfy the left conjunct, \(\psi \) must be caused. But after causing \(\psi \), the right conjunct is not satisfied, and \(\chi \) must be caused too. In general, the two conjuncts are repeatedly enforced until both are satisfied. This is achieved by combining the function \(\textsf{fp}\) (performing a fixed-point computation) and \(\textsf{enf}^+_{\textsf{and},\varphi _1,\varphi _2,v,ts}\) that calls the function \(\textsf{enf}^+\) on both \(\varphi _1\) and \(\varphi _2\) if none of these formulae is satisfied. In our extended report [42], we prove the termination of this fixed-point computation

  • Suppressing \(\exists x.~\varphi _1\) (Algorithm 2, \(\textsf{enf}^-\) l. 13). The suppression of \(\exists \) follows a similar pattern, but this time there are \(\textsf{AD}_{|\sigma |}(\varphi _1)\) rather than just 2 cases to consider, corresponding to all potential values of the (past-guarded) variable x. Similar to the previous case, we prove termination in our extended report [42].

  • Causing \(\varphi _1 {\textsf{U}}_{[a,b]} \varphi _2\), \(b \ne \infty \) (Algorithm 2, \(\textsf{enf}^+\) l. 17–22). There are two cases for causing \(\varphi _1 {\textsf{U}}_I \varphi _2\): we cause \(\varphi _1\) and generate the future obligation \(\textsf{fo}_{\tau ,{\textsf{U}},I,\varphi _1,\varphi _2}\) if \(I \ne [0,0]\) or \(b = \bot \); otherwise, we cause \(\varphi _2\) and \(\texttt{TP}\).

Example 7

Let us enforce \(\varphi _\textsf{del}\) on \(\sigma _2\). Consider the following abbreviations:

$$\begin{aligned}\begin{gathered} \varphi _{\textsf{del}} \equiv {\square }\varphi _{\forall } \qquad \varphi _{\forall } \equiv \forall c, d, u.\,\mathsf {deletion\_request}\left( c, d, u\right) \rightarrow {\lozenge }_{[0,30]}\textsf{delete}\left( c, d, u\right) \\ \varphi _{{\textsf{U}}} \equiv (\texttt{TP}\rightarrow \top ) {\textsf{U}}(\texttt{TP}\wedge \lnot \varphi _{\forall }) \;\; E_1 \equiv \mathsf {deletion\_request}(2,1,1) \;\; E_1' \equiv \textsf{delete}(2,1,1) \\ fo _2^{x,y} \equiv (\lambda \tau '.~{\lozenge }_{[0,x]-(y-\tau ')} \left( \texttt{TP}\wedge \textsf{delete}\left( c,d,u\right) \right) , \lbrace c \mapsto 2, d \mapsto 1, u \mapsto 1\rbrace , +) \end{gathered}\end{aligned}$$

Figure 7 shows our algorithm’s execution.

figure h

Initially, \(\textsf{enf}\) decomposes its goal \(\varPhi = \texttt{TP}\wedge \varphi _{\textsf{del}}\) into the present obligations \((\texttt{TP},\emptyset ,+)\) and \((\varphi _{\textsf{del}},\emptyset ,+)\). The former is discharged by causing \(\texttt{TP}\); the latter is unrolled into the present obligation \((\varphi _{\forall },\emptyset ,+)\) and the future obligation \( fo _1 = (\textsf{fo}_{10, {\textsf{U}},[0,\infty ),\top ,\lnot \varphi _{\forall }},\emptyset ,-) = (\lambda \_.\, \varphi _{{\textsf{U}}}, \emptyset , -)\). The present obligation \((\varphi _{\forall },\emptyset ,+)\) is violated, since \(\mathsf {deletion\_request}(2,1,1)\) is satisfied but at this point there is no corresponding \(\textsf{delete}\). In this case, \(\textsf{enf}_{10,\bot }^+\) generates the future obligation \( fo _2^{30,10}\). Satisfying this future obligation guarantees the satisfaction of \(\varPhi \), hence the algorithm proceeds. Next, the algorithm processes the timestamp 10 ‘in the nick of time’. The function \(\textsf{enf}\) computes \(\varPhi = fo _1(10)\wedge fo _2^{30,10}(10)=\varphi _{{\textsf{U}}}\wedge {\lozenge }_{[0,30]} (\texttt{TP}\wedge E_1')\) and calls \(\textsf{enf}_{10,\top }^+\) on \(\varPhi \). First, it decomposes \(\varPhi \) into the present obligations \( po _1 = (\varphi _{\forall },\emptyset ,+)\) and \( po _2 = ({\lozenge }_{[0,30]} (\texttt{TP}\wedge E_1'),\emptyset ,+)\) and the future obligation \( fo _1\). The present obligation \( po _1\) is vacuously satisfied, since no \(\mathsf {deletion\_request}\) takes place. In contrast, the satisfaction of \( po _2\) can rely on the satisfaction of the future obligation \(( fo _2^{30,10},\emptyset ,+)\) at the next time-point. Hence, the enforcer emits \(\textsf{NoCom}\) and propagates the future obligations \(X'=\lbrace fo _1, fo _2^{30,10}\rbrace \) to the next time-point. The timestamp 11 is also processed ‘in the nick of time’. The goal \(\varPhi = fo _1(11)\wedge fo _2^{30,10}(11)=\varphi _{{\textsf{U}}}\wedge {\lozenge }_{[0,29]} (\texttt{TP}\wedge E_1')\) is computed, and reduced to the future obligations \(X'=\lbrace fo _1, fo _2^{29,11}\rbrace \). Similar iterations occur until timestamp 40, when the goal becomes \(\varPhi = fo _1(40)\wedge fo _2^{1,39}(40)=\varphi _{{\textsf{U}}}\wedge {\lozenge }_{[0,0]} (\texttt{TP}\wedge E_1')\). Here, \(\textsf{enf}_{40,\top }^+\) produces the present obligations \((\texttt{TP},\emptyset ,+)\) and \((E_1',\emptyset ,+)\), which are discharged by causing \(\texttt{TP}\) and \(E_1'\), respectively. Thus, \(D_C= \lbrace \texttt{TP},E_1'\rbrace \) and the command \(\textsf{PCom}(\lbrace E_1'\rbrace )\) is emitted, resulting in \((40, \lbrace E_1'\rbrace )\) being inserted into the trace. The future obligations \(X'=\lbrace fo _1\rbrace \) are propagated to the next timestamp. Similar iterations occur until timestamp 50. At this point, \(b = \bot \) and the trace is already compliant, so the enforcer responds with \(\textsf{RCom}(\emptyset ,\emptyset )\).

Fig. 7.
figure 7

Enforcement of the formula \(\varphi _\textsf{del}\) on trace \(\sigma _2\)

5.4 Correctness

Let \(\varphi \) be a closed formula to be enforced. The proofs of all lemmata are given in our extended report [42]. First, recall the following standard definition of safety [6]:

Definition 6

P is a safety property iff for any \(\sigma \in \mathbb {T}_\omega \setminus P\), there exists a finite prefix \(\sigma ' \in \mathbb {T}_f\) of \(\sigma \) such that for all \(\sigma '' \in \mathbb {T}_\omega \), we have \(\sigma \cdot \sigma '' \notin P\). A formula \(\varphi \) is a safety formula when \(\mathcal {L}(\varphi )\) is a safety property.

Our algorithm can enforce formulae that are not safety formulae. This is the case, e.g., for any \(\psi \vee {\lozenge }\chi \equiv \lnot (\lnot \psi \wedge \lnot (\top {\textsf{U}}\chi ))\), where \(\psi \) types to \({\mathbb {C}}\). In this case, enforcement is performed greedily: if the monitor cannot construct a proof of \({\lozenge }\chi \) (which occurs whenever \(\chi \) cannot be satisfied in the present), then \(\psi \) is caused. Thus our algorithm actually enforces a stronger formula, which we denote by \([\psi \vee {\lozenge }\chi ]_+ \equiv \lnot (\lnot \psi \wedge ^{\textsc {R}\omega } \lnot (\top {\textsf{U}}\chi ))\), where \(\wedge ^{\textsc {R}\omega }\) has the semantics

$$\begin{aligned} &v,i \vDash _\sigma \varphi \wedge ^{\textsc {R}\omega } \psi {} & {} \text {iff }v,i \vDash _\sigma \varphi \text { and }\exists \sigma '.\,v,i \vDash _{\sigma \vert _{..i}\cdot \sigma '} \psi . \end{aligned}$$

This semantics states that \(\varphi \wedge ^{\textsc {R}\omega } \psi \) holds whenever \(\varphi \) holds on \(\sigma \) at time-point i and there exists at least one extension of the prefix \(\sigma |_{..i}\) on which \(\psi \) holds. The formula \([\psi \vee {\lozenge }\chi ]_+\) thus requires than \(\psi \) holds on \(\sigma \) at time-point i and \({\lozenge }\psi \) holds on \(\sigma \) at time-point i for any extension of \(\sigma \mid _{..i}\). The formula \([\psi \vee {\lozenge }\chi ]_+\), unlike \(\psi \vee {\lozenge }\chi \), is safety. In our extended report [42], we define a similar transformation \([\bullet ]_p\), \(p \in \{+,-\}\) for all operators and prove

Lemma 4

For any \(\varphi \) such that \(\varGamma \vdash \varphi : \{{\mathbb {C}}\}_p\), we have \(v, i \models _{\sigma } p[\varphi ]_p \Longrightarrow v, i \models _{\sigma } p\varphi \). In particular, \(\mathcal {L}([\varphi ]_+) \subseteq \mathcal {L}(\varphi )\).

We prove that \(\mathcal {E}_\varphi \) soundly enforces \([\varphi ]_+\), and hence \(\varphi \):

Theorem 1

(Soundness). If \(\varphi \in \text {EMFOTL}\), the enforcer \(\mathcal {E}_\varphi \) is sound with respect to \(\mathcal {L}([\varphi ]_+) \subseteq \mathcal {L}(\varphi )\). As a consequence, \(\varphi \) is enforceable.

In our model, transparent enforcement of non-safety formulae such as \(\psi \vee {\lozenge }\chi \) is generally not possible, since the necessity to cause \(\psi \) depends on future events:

Lemma 5

If a property admits a transparent enforcer, it is a safety formula.

Thus, when enforcing a non-safety formula \(\varphi \), one can at best achieve transparency with respect to some sound safety approximation \(\varphi '\) of \(\varphi \). We prove:

Theorem 2

(Transparency). If \(\varphi \in \text {EMFOTL}\), the enforcer \(\mathcal {E}_\varphi \) is transparent with respect to \(\mathcal {L}([\varphi ]_+)\).

By imposing more constraints on the formulae (e.g., the formula \(\chi \) must not depend on the future in \(\psi \wedge ^{{\mathbb {S}}\textsc {L}} \chi \)), one can obtain an EMFOTL fragment for which \([\varphi ]_+=\varphi \) and the enforcer \(\mathcal {E}_\varphi \) is transparent (see our extended report [42]).

6 Evaluation

Fig. 8.
figure 8

Selected events and policies from Arfelt et al. [7]

We implemented our type system and enforcement algorithm in a tool, called WhyEnf, consisting of 2 800 lines of OCaml code. WhyEnf uses a modified version of WhyMon [49], which we call WhyMon*. It ignores the explanations’ structures (not required by our algorithm) and returns only Boolean verdicts.

Our evaluation aims to answer the following research questions:

  1. RQ1.

    Is EMFOTL expressive enough to formalize real-world policies?

    Is manual formula rewriting necessary, as in previous works [14, 40]?

  2. RQ2.

    At what maximum event rate can WhyEnf perform real-time enforcement?

  3. RQ3.

    Do WhyEnf’s performance and capabilities improve upon the state-of-the-art?

The notion of ‘real-world policies’ in RQ1 is domain-dependent. In the following, we demonstrate our approach’s effectiveness in the case of privacy regulations.

Case study. Arfelt et al. [7] define events and MFOTL formulae formalizing core GDPR provisions that they monitor on a trace produced by a real-world system [24]. Relevant events (superscripted by their number of occurrences in the trace) and formulae are shown in Fig. 8 and Examples 1 and 3. We pre-process the trace to obtain 3 846 time-points containing 5 630 system events distributed over 515 d. We interpret the ‘Lawyer review’ and ‘Architect review’ events as both \(\textsf{use}\) and \(\textsf{share}\) (sharing with third-parties) events, and the ‘Abort’ events as both \(\textsf{revoke}\) (revoking consent) and \(\mathsf {deletion\_request}\). Otherwise, we follow Arfelt et al.’s pre-processing. We make the following assumptions [40]: \(\textsf{use}\) events are suppressable, while \(\textsf{delete}\), \(\textsf{inform}\) (informing the user), and \(\textsf{notify}\) (notifying a third-party) events are causable. All metric constraints are specified in days.

RQ1: Expressiveness. Except for \(\varphi _{\textsf{min}}\), all formulae are in EMFOTL. Unlike in previous works [15, 18, 40], no further policy engineering (e.g., manual rewriting to equivalent formulae in supported fragments) is needed. For all enforceable formulae except \(\varphi _{\textsf{lim}}\), our algorithm guarantees transparent enforcement. For \(\varphi _{\textsf{lim}}\), which contains an unbounded \({\lozenge }\) operator, non-transparent enforcement is possible by enforcing the stronger formula \(\varphi ^b_{\textsf{lim}}={\square }(\forall c, d, u.\,\textsf{collect}(c, d, u) \rightarrow {\lozenge }_{[0,b]}\textsf{delete}(c, d, u))\) for any \(b \in \mathbb {N}\). The formula \(\varphi _{\textsf{min}}\), capturing data minimization, is intrinsically non-enforceable, as a sound \(\mathcal {E}_{\varphi _{\textsf{min}}}\) must either always suppress \(\textsf{collect}\), or eventually cause \(\textsf{use}\), which is only suppressable.

WhyEnf’s type system helps determine appropriate suppressible and causable events. For instance, if \(\textsf{use}\) was marked as only-observable, the type checker would state that \(\varphi _{\textsf{law}}\) is not enforceable and suggest to make \(\textsf{use}\) suppressible, or otherwise make either \(\textsf{consent}\) or \(\mathsf {legal\_ground}\) causable. Since \(\textsf{use}\) actually is suppressable, the type checker concludes that \(\varphi _{\textsf{law}}\) is transparently enforceable.

RQ2: Maximum event rate. We enforce the enforceable formulae from Fig. 8, i.e., all but \(\varphi _{\textsf{min}}\). As we do not have access to the SuS, we simulate online enforcement by reproducing [45] the events from the above trace to WhyEnf at the speed specified by the trace’s timestamps. We also consider different accelerations of the original trace’s real-time behavior to challenge WhyEnf. We measure WhyEnf’s latency \(\ell \) and processing time t for each time-point. Latency is the time delay between the emission of a time-point to WhyEnf and the reception of the corresponding command, whereas processing time is the time WhyEnf effectively takes to process the time-point. We report the average latency (\(\textsf{avg}_{\ell }(a)\)) and maximum latency (\(\textsf{max}_{\ell }(a)\)) given an acceleration a, as well as the average processing time (\(\textsf{avg}_t\)), and the maximum processing time (\(\textsf{max}_t\)) all computed over the entire trace. If \(\textsf{max}_{\ell }(a)\) is smaller than the interval \(\frac{1}{a}\) between two timestamps in the accelerated trace, then the real-time condition (Sect. 3.1) is met assuming that the SuS’s and communication latency are small enough.

All measurements were performed on a 2.4 GHz Intel i5-1135G7 CPU with 32 GB RAM. For each formula and acceleration \(a \in \{10^5 \cdot 2^0, \dots , 10^5 \cdot 2^9\}\), we plot \(\textsf{max}_{\ell }(a)\), the function \(\frac{1}{a}\) (right y-axis), and the corresponding average event rate \(\textsf{avg}_{er}(a)\) (left y-axis) in Fig. 9. We include similar plots for WhyMon* and EnfPoly and latency profiles for individual runs in our extended report [42].

Fig. 9.
figure 9

RQ2: Maximum latency of WhyEnf and event rate for the formulae in Fig. 8.

As presented in Fig. 9, for all formulae, WhyEnf meets the real-time condition for all accelerations up to \(4\cdot 10^5\), which corresponds to a maximum latency of 96 ms and an average event rate of 51 events/s. Hence, even though the analyzed trace specifies time intervals in days, the real-time enforcement of the same trace can in fact be performed for sub-second intervals. Note that the average latency is much lower (20 ms for the most challenging policy), with the maximum latency occurring when many events occur within a short time span. The two formulae that only define future obligations, \(\varphi _{\textsf{lim}}\) and \(\varphi _{\textsf{del}}\), have much lower maximum latency, of 14 and 19 ms, respectively, corresponding to an average event rate of about 600 events/s. Due to proactivity, the enforcer does not need to keep the history of past events for these formulae. Overall, our experiments show that WhyEnf can efficiently enforce a real-world SuS.

RQ3: Comparison with the state of the art. We compare WhyEnf’s performance to its two most closely related tools: WhyMon*, which provides similar expressiveness as WhyEnf but no enforcement, and EnfPoly [39], the only tool supporting non-proactive enforcement of an MFOTL fragment. In addition to the real-world log [24], we generate synthetic traces with \(n \in \{100 \cdot 2^0, \dots , 100 \cdot 2^8\}\) time-points each containing \(k \in \{2^0,\dots ,2^8\}\) random events. We report \(\textsf{avg}_t\) for the three tools and six formulae in Fig. 11, imposing a 10-minute timeout (t.o.).

WhyMon* cannot monitor \(\varphi _{\textsf{lim}}\), as the formula has an unbounded \({\lozenge }\) operator. For all other formulae, WhyMon* satisfies the real-time condition for accelerations \(a \le 10^5\). WhyEnf’s latency is at most twice WhyMon*’s for \(\varphi _{\textsf{law}}\) and \(\varphi _{\textsf{con}}\) as the enforcer calls the monitor at least once per iteration and also performs fixed-point computations (Fig. 10). In contrast, WhyEnf can enforce \(\varphi _{\textsf{lim}}\) and has significantly (up to 22 times) lower latency for \(\varphi _{\textsf{inf}}\), \(\varphi _{\textsf{sha}}\), and \(\varphi _{\textsf{del}}\). Unlike WhyMon*, WhyEnf is able to lazily evaluate implications involving future obligations, which improves its runtime performance. WhyEnf’s processing time also scales better than WhyMon*’s for large values of n and k (Fig. 11).

Only \(\varphi _{\textsf{law}}\) and \(\varphi _{\textsf{con}}\) are transparently enforceable without proactivity. We enforce them using EnfPoly after manually rewriting them into equivalent formulae in EnfPoly’s fragment. WhyEnf’s average and maximum latencies are higher than EnfPoly’s, but WhyEnf’s algorithm covers a much larger fragment of MFOTL than EnfPoly, which makes computating verdicts more costly. The same behavior is observed in terms of average processing time (Fig. 11).

Fig. 10.
figure 10

RQ2–3: Latency and processing time for the largest a such that \(\textsf{max}_\ell (a) \le 1/a\).

Fig. 11.
figure 11

RQ3: Average processing time (ms) for different trace and time-point sizes.

7 Related Work

Security automata [26, 58] were first used for enforcement by terminating the SuS. Fredrikson et al. [31] also terminate the SuS upon violation detection, but use symbolic automata which allow policies to refer to the SuS’s state. Bauer et al. [21] investigate enforcers that can cause and suppress events, as do Ligatti et al. [47], who use edit automata with the ability to buffer events. Ngo et al. [51] study policy enforcement for reactive systems for which they disallow the enforcer to buffer events or inspect SuS code. Basin et al. [15] distinguish between suppressable and only-observable events, without considering causation. More complex bidirectional enforcement [3, 4] and enforcement through delaying events [27, 54] have also been proposed. Pinisetty et al. [55] further allow the enforcer to inspect the SuS’s code to perform predictive enforcement.

Most runtime enforcement approaches (and tools [28, 29]) rely on automata as policies. Metric interval temporal logic formulae can be enforced via translation to timed automata [53, 57]. Basin et al. [11, 12] use dynamic condition response graphs [36] to formalize and enforce obligations in real time by suppressing and (proactively) causing events. Finally, controller synthesis tools for LTL [25, 44, 60], Timed CTL [22, 52], or MTL [38, 46] can generate enforcement mechanisms.

To the best of our knowledge, only a few approaches enforce first-order temporal policies. Hallé and Villemaire [33, 34] develop a monitor for LTL-FO\(^+\), a first-order variant of future-only linear temporal logic. They use the monitor to block the system in case of detected policy violations, in the spirit of the work on security automata [26, 58]. Hublet et al. [39,40,41] developed the EnfPoly tool that enforces policies from a fragment of MFOTL that can contain future operators, but only nested with past ones such that the formula overall does not refer to the future. Independently, Aceto et al. [2,3,4,5] consider the safety fragment of Hennessy-Milner Logic (HML) with recursion as their policy language. They generalize HML to allow quantification over event parameters, but do not support time constraints. They also focus on instrumentation scenarios where all events are suppressable.

A satisfiability checking tool [30] and many runtime monitoring tools support (different fragments of) MFOTL [23], including MonPoly [13, 17,18,19], VeriMon [9, 10, 59] and DejaVu [35]. Lima et al. [48] recently introduced Explanator2, an MTL monitor that outputs explanations. They later extended their work to MFOTL with the WhyMon tool [49], upon which our enforcer relies. WhyMon supports a large fragment of MFOTL as it uses partitioned decision trees to represent variable assignments. To the best of our knowledge, all existing monitoring tools only support safety formulae of the form \({\square }\varphi \). Our work additionally supports (non-transparent) enforcement of some non-safety formulae.

8 Conclusion

We have presented the first proactive real-time enforcement algorithm and an efficient tool, WhyEnf, for metric first-order temporal logic. Our approach lends itself to a number of extensions. For instance, WhyMon’s runtime performance can be optimized for large formulae. Features like complex data types [50], let bindings [61], and aggregations [16] would further improve our enforcer’s expressiveness. Finally, refinements of the type system when the same event can be both caused and suppressed in different contexts would be a useful addition.