Learning is Change in Knowledge: Knowledge-Based Security for Dynamic Policies

In systems that handle confidential information, the security policy to enforce on information frequently changes: new users join the system, old users leave, and sensitivity of data changes over time. It is challenging, yet important, to specify what it means for such systems to be secure, and to gain assurance that a system is secure. We present a language-based model for specifying, reasoning about, and enforcing information security in systems that dynamically change the security policy. We specify security for such systems as a simple and intuitive extensional knowledge-based semantic condition: an attacker can only learn information in accordance with the current security policy. Importantly, the semantic condition is parameterized by the ability of the attacker. Learning is about change in knowledge, and an observation that allows one attacker to learn confidential information may provide a different attacker with no new information. A program that is secure against an attacker with perfect recall may not be secure against a more realistic, weaker, attacker. We introduce a compositional model of attackers that simplifies enforcement of security, and demonstrate that standard information-flow control mechanisms, such as security-type systems and information-flow monitors, can be easily adapted to enforce security for a broad and useful class of attackers.


I. INTRODUCTION
Given the wealth of confidential information handled by many different computer systems, it is important to ensure that systems enforce appropriate security on the information that they manipulate.But what constitutes "appropriate security" changes over time, even during a single execution of the system: users join the system and can now view confidential information; users leave the system and are no longer allowed to view confidential information; the sensitivity of data changes over time, affecting the set of users that can view the data.
In the presence of such dynamic changes to the desired security policy, it is challenging to specify what it means for a system to be secure, let alone to gain assurance that a system correctly enforces security.Previous approaches that aim to provide strong information security either ignore the dynamic nature of security policies in their security guarantee (e.g., [32,33]), or introduce complex and unintuitive definitions of security and/or use non-standard enforcement mechanisms (e.g., [6,16,34]).
We present a language-based model for specifying, reasoning about, and enforcing information security in systems that dynamically change the security policy.Our semantic security condition is simple, intuitive, extensional, and defined in terms of an attacker's knowledge: an attacker that can observe program execution should learn information only in accordance with the current security policy.
Importantly, the semantic security condition is parameterized on the abilities of the attacker.Knowledge-based semantic security conditions are intended to restrict what and when an attacker learns information.Learning is about change in knowledge, and so we must consider how the knowledge of an attacker changes as it makes observations.In many practical scenarios, the perfect recall attacker is too strong.An observation that gives a weak attacker new information may be "old news" for a strong attacker with perfect recall.We enforce our semantic security condition for a broad and practical set of attackers using straightforward adaptations of standard information-flow security mechanisms (e.g., [3,28]).
We regard a security policy as a relation over a set L of security levels.Intuitively, security policies specify what information flows are permitted between security levels.Policies must be reflexive, and may be (but are not required to be) partial orders or lattices.Policies can encode information-flow lattices [11] and intransitive relations such as those used for intransitive noninterference [23,35].We assume that the set of security levels L is fixed, but allow the policy to change during program execution.
Motivating scenario.Consider a company's documentmanagement system that is accessible by all of the company's employees.It contains many documents, some of which are sensitive, meaning that only certain employees may use them.As an employee joins or leaves the company, or is promoted or transferred, the set of documents that the employee may access changes.The information security policy for this document-management system specifies who may use which documents, and it changes over time.Indeed, the security policy itself is part of the state of the system, and part of the system's functionality is the ability for some users to modify the security policy.
Even a relatively simple document-management system can reveal information about documents in unexpected ways.For example, suppose the documents are indexed to facilitate search.Because the index contains information about keywords that appear in sensitive documents, the index contains sensitive information: if a user is given unrestricted access to the index, the user may learn confidential information she is not permitted to learn.Traditional access control mechanisms would not suffice to enforce the desired security, since a user may learn information about documents through the index without ever attempting to access the document.
We thus seek to enforce strong information security, defined in terms of the knowledge of agents interacting with the system.The definition of security, and the enforcement of it, is complicated by the dynamic nature of security policies.However, our definition is simple and intuitive: an agent that observes program execution should learn information only if permitted by the current security policy.
The following program allows user U to learn about documents classified as Nuclear (that is, changes the current security policy so that (Nuclear , U ) ∈ ), and outputs the keywords of document nuke 1 to user U .(We assume that the indexing functionality of the system can determine the keywords of a document, and the keywords of a document reveal information about the document's content.)The program then removes permission for U to learn about Nuclear documents (that is, changes the current security policy so that (Nuclear , U ) ∈ , perhaps due to U being reassigned to a different department), and outputs the keywords of document nuke 2 to U .Both documents are classified as Nuclear.
P 1 : Allow info flow from Nuclear to U Output keywords(nuke 1 ) to U Disallow info flow from Nuclear to U Output keywords(nuke 2 ) to U This program is insecure, in that user U learns information about document nuke 2 at a time when the security policy does not allow it.User U also learns about document nuke 1 , but does so when the security policy permits it.
Attacker model.Consider the following code, that outputs confidential information to user U at a time when U is permitted to learn the information, and the same information again at a time when U is not permitted.Should this program be regarded as secure or not?At the first output, U learns information about document nuke 1 .If U is a powerful attacker who remembers the first output, then when the confidential information is output again, U learns nothing new.From our description of the security condition, this program is secure: the attacker learns information only in accordance with the currently enforced policy.However, intuitively, we would like to regard this program as insecure: it outputs information about nuke 1 to U at a time when this is not permitted.Indeed, for a more realistic attacker, who may not remember every output it has observed, the last output may enable the attacker to learn information about nuke 1 at a time when this isn't permitted.
A suitable definition of security should permit us to reject both programs P 1 and P 2 , even though one of them is secure against a powerful attacker.We therefore parameterize our definition of security with respect to an attacker: a program is secure against attacker A if A learns information only in accordance with the current security policy.
Security thus depends on the ability of the attacker.Rather than being an artifact of our technical development, we believe that this is a fundamental and important notion.Our intuitions about information security revolve around the idea of restricting what an attacker is permitted to learn.Learning is about change in knowledge: an attacker learns something from an event if the attacker's knowledge after the event is more precise than the attacker's knowledge before.In the presence of dynamic security policies, it is not sufficient to simply consider the most powerful possible attacker: we must also consider changes in the knowledge of weaker, more realistic, attackers.
Ideally we would like to ensure that a program is secure against as many attackers as possible.However, it may not be possible to be secure against all possible attackers (as we will discuss later).This begs the question "which set of attackers we should strive to ensure security against?" We develop a compositional theory of attackers that gives insight into the security condition, and simplifies enforcement.Specifically, we show that there is a class of simple attackers that are easy to reason about, and if a program is secure against this class of simple attackers then the program is secure against many other attackers, including logicallyomniscient attackers with perfect recall, and with bounded memory.This compositional theory both enables reasoning about the security of programs, and simplifies enforcement.
Contributions.This work makes three key contributions.
• We present a novel semantic security condition suitable for dynamic security policies.The security condition is intuitive, extensional, and knowledgebased, and is suitable for a language that permits arbitrary changes to the security policy.The semantic security condition is parameterized on an attacker, and a program may be secure against a powerful attacker and insecure against a weaker attacker.control techniques to handle dynamic security policies in a language that can be extended with expressive security-relevant features.
• We introduce a compositional model of attackers, which simplifies both the security condition and the enforcement mechanisms.We prove that enforcing security for a simple and intuitive class of attackers implies security for a much broader class of attackers.
The remainder of the paper is structured as follows.In Section II we present a simple interactive imperative language.We present and discuss semantic security conditions for this language in Section III.We extend the language in Section IV to allow the runtime representation, inspection, and manipulation of security policies.Section V shows that existing information-flow control mechanisms (a securitytype system and a dynamic information-flow monitor) can be easily adapted to enforce our semantic security condition.We can further extend the language with first-class security levels and fine-grained security policies without significant change to the semantic security condition (Section VI).We discuss related work in Section VII and conclude in Section VIII.

II. LANGUAGE
We present a simple imperative interactive language that contains an explicit command for changing the current security policy.The language can perform input and output on channels.We assume that there is one channel for each security level in L. Our semantic security conditions will be concerned with protecting the confidentiality of inputs received on channels.
Syntax. Figure 1 presents the language syntax.Language commands are standard, with the exception of input and output commands, and command setPolicy( ), which sets the current security policy to .We do not specify how security policies are denoted, but assume that some mechanism exists.In later sections, we will extend the language to allow security policies to be specified using language mechanisms.Input command input x from receives an input from channel and assigns the value to variable x.Output command output e to evaluates expression e and outputs the resulting value on channel .
Expressions e consist of program variables x, values v, and binary operations over expressions.We use ⊕ to range over total binary relations over values.For simplicity, we restrict values to integers n.An input stream is a sequence of values representing the pending inputs on a channel.We use metavariable vs to range over input streams, and write v : vs for the input stream with first element v, and remaining elements vs.An input environment is a function from L to input streams.Metavariable w ranges over input environments.For input environment w and security level ∈ L, w( ) is the input stream for channel .Note that, because our language is deterministic, it is sufficient to model input via streams-Clark and Hunt show that, for deterministic programs, quantification over all streams expresses arbitrary interactive input strategy [10].
A configuration is a tuple c, m, w, consisting of command c, memory m, input environment w, and security policy .Command c is the remainder of the program to execute, m is the current memory, w is the current input environment, and is the current security policy.Figure 2 presents an operational semantics for the language.either input events i (v, ) or output events o(v, ), indicating, respectively, the input or output of value v on channel .We use α = to indicate that no event was emitted during the execution step.We use E to denote the set of all possible events, and E( ) to denote the set of possible events on channel .
We write m(e) = v to indicate that expression e evaluates to value v using memory m to look up the value of program variables.We write m[x → v] for the memory that maps program variable x to value v and otherwise behaves the same as memory m.Similarly, we write w[ → vs] for the input environment that maps channel to input stream vs and otherwise behaves the same as w.
The inference rules for the semantics are mostly standard.Command setPolicy( ) modifies the configuration to make policy the current policy.Input command input x from inputs value v from input stream w( ), updates the memory to map x to v, updates the input environment to remove v from input stream w( ), and emits event i (v, ).Output command output e to evaluates e to value v, and emits event o(v, ).
We assume that there is a distinguished memory m init and a distinguished security policy init that are used as the initial memory and security policy, respectively, for any program execution.For concreteness, we assume in the rest of the paper that the initial security policy is the identity relation over security levels: init = Id = {( , ) | ∈ L}.
Our semantic security conditions will be concerned with the confidentiality of initial input environments.As such, there is no distinguished initial input environment.
Traces.Traces are finite sequences of events.We use metavariable t to range over traces, and write t 1 • t 2 for the concatenation of traces t 1 and t 2 .We write for the empty trace (and also use it to denote the absence of an event in an execution step).We write |t| for the length of trace t.
We write t for the restriction of trace t to events on channel .More formally, we have We say that configuration c 0 , m 0 , w 0 , 0 emits trace t on channel ending with policy k (written c 0 , m 0 , w 0 , 0 ⇓ (t, k )) if there are k +1 configurations c i , m i , w i , i for i ∈ 0..k such that Intuitively, if c, m init , w, init ⇓ (t, ) then an observer of channel may observe trace t during the execution of command c with initial input environment w, and policy is the policy enforced when the last event of t was emitted.

III. SECURITY
We define security of a program in terms of the knowledge of an attacker that observes program execution.Conceptually, the definition of security is straightforward: an execution of a program is secure if an attacker learns information about the initial input environment only in accordance with the current security policy.
In this section, we define attackers as entities that observe the execution of a program, and define the knowledge of an attacker.We then state two versions of the semantic security condition and explore some of the consequences.

A. Attackers and attacker knowledge
As discussed in the introduction, a program may be secure against a powerful attacker, but insecure against a weaker attacker.We thus define attackers, and will parameterize our definition of security with respect to the attacker that is observing program execution.
An attacker is a state-based machine that observes a subset of events during a program's execution, and updates its state accordingly.We assume that all attackers know the source code of the program generating the events, and that attackers are logically omniscient.Attackers differ in their ability to remember the observations they have made.We will define the attacker's knowledge to be the set of initial input environments that could have resulted in a sequence of observations that caused the attacker to be in its current state.
Formally, attacker A is a tuple A = (S A , s init , δ A ) where • S A is a set of attacker states; • s init ∈ S A is the initial attacker state; and • δ A : S A × E → S A is the transition function that describes how the attacker's state changes due to events the attacker observes.Note that δ A is a function, and so state transitions are deterministic.Given trace t and attacker A = (S A , s init , δ A ), we write A(t) to denote the attacker's state after observing trace t.
We assume that attacker A is able to observe only events on a single channel, and refer to that channel as the level of A.
Note while this is not uncommon in literature [27], this is different from conventional approaches where attacker observes events from all channels such that .In our case, the choice is more than a matter of preference-the conventional definition would be unsuitable because of the dynamic nature of .
Example attackers.We give four examples of attackers that will be of later interest.The "perfect attacker" A Per has perfect recall: it remembers all observations.The set of states for A Per is the set of traces.The attacker's initial state is the empty trace, and the transition function concatenates the latest observable event to the attacker's state: δ APer (s, α) = s•α.The perfect attacker knows more than any other attacker (which will be stated and proved later).
A significantly weaker class of attackers are "bounded memory" attackers, A last-i , that remember the last i observed events (and the total number of events observed).More formally, the set of attacker states is the set of pairs of natural numbers (counting the number of observations), and traces of up to length i.The initial state is the pair (0, ), and the transition function is defined as δ A last-i ((j, t), α) = (j + 1, t ) where t is equal to the last k events of t • α, where k is the minimum of i and the length of t • α.
Another class of attackers that will be of interest are the "i-th event only" attackers A i-only which simply count the number of observed events, and remember only the ith event.More formally, the set of attacker states is the set of pairs of natural numbers (counting the number of observations), and, optionally, events (recording the ith event): The initial state is (0, ).The transition function is defined as follows.
An even weaker attacker is the "no memory" attacker A ∅ who has only a single state s init , and thus pays no attention to any observations: Attacker knowledge.Given program c, we define the knowledge of attacker A with current state s and level to be the set of initial input environments that could have resulted in the attacker's current state by observing execution of command c.We write k(c, A, , s) for the attacker's knowledge, and define it as follows.
and A(t) = s} Intuitively, the set k(c, A, , s) is the set of initial input environments that attacker A with state s believes are possible.Thus, a smaller set means that the attacker has better, or more precise, knowledge.
The perfect attacker A Per has the most precise knowledge out of any possible attacker, since A Per remembers all observable events.Theorem 1.Let A = (S A , s init , δ A ) be an attacker.Then for all commands c, all security levels , all initial input environments w, and all traces t such that c, m init , w, init ⇓ (t, ) we have Proof: Let c, , w and t be fixed, and assume c, m init , w, init ⇓ (t, ).First note that w ∈ k(c, A Per , , A Per (t)) if and only if c, m init , w , init ⇓ (t, ).Suppose that there is some w such that w ∈ k(c, A, , A(t)) and w ∈ k(c, A Per , , A Per (t)).But then c, m init , w , init ⇓ (t, ).Thus w ∈ k(c, A, , A(t)), a contradiction.

B. Security definition
Our definition of security is, intuitively, that the attacker learns information only in accordance with the current security policy.Since we are interested in protecting the initial input environment, we need to define what the attacker is permitted to learn about the initial input environment.Towards this end, we define an equivalence relation over input environments: -equivalence according to , written ≈ .Two input environments are related to each other by ≈ if the two input environments have identical input streams for all security levels that are permitted to flow to level according to policy .Intuitively, if w ≈ w then policy would not allow an attacker with level to distinguish the input environments w and w .More formally, We write [w] to denote the equivalence class of w under relation ≈ .
Given this interpretation of how security policies are intended to restrict attacker knowledge of initial input environments, we can now state the definition of security.
Definition 1 (Security for input environment w).Command c is secure against attacker A = (S A , s init , δ A ) with level for initial input environment w if for all traces t, events α, and policies such that c, m init , w, init ⇓ ((t • α), ) we have Security requires that, for each observation α that the attacker makes, the attacker's new knowledge -k(c, A, , A(t•  α)), the left-hand side of the equation-is no more precise than the combination of the attacker's previous knowledge and the knowledge about the initial input environment allowed by the current policy-k(c, A, , A(t)) ∩ [w] , the right-hand side of the equation.

C. Security against attackers
The definition of security depends on the knowledge of the attacker.Thus, different programs will be secure against different attackers.For example, consider the following program, P 3 , a version of the pseudocode program from the introduction.There are three security levels L = {A, B, C}, policy AB→C allows information flow from level A to C and from level B to C, and B→C allows information flow from B to C, but not from A to C.
This program reads inputs from channels A and B, stores them in variables a and b, sets the policy to AB→C , and outputs a + b to channel C. It then sets the policy to B→C and outputs variable b to channel C. It is secure against the "no memory" attacker A ∅ with any level .Indeed, every program is secure against A ∅ , since the knowledge of A ∅ never changes.
All executions of P 3 are secure against A Per with level C. Consider an execution with A Per observing channel C. The attacker observes the sum a + b, say 12.At this point in the execution, the attacker's knowledge is the set of all initial input environments w such that the first elements of input streams w(A) and w(B) sum to 12.This change in knowledge is permitted by the current security policy AB→C which allows the attacker to learn anything and everything about the initial input streams w(A) and w(B) The attacker next observes the value of variable b, say 7. The attacker's knowledge has improved: it now knows the exact values for the first elements of input streams w(A) and w(B).The current security policy is B→C .Clearly the attacker has learned the first element of the initial input stream w(B), which is permitted by policy B→C .But the attacker has also learned the first element of the initial input stream w(A), which is not permitted by the policy.Nonetheless, the execution is secure, since the attacker's new knowledge is no more precise than what may be obtained by combining the attacker's previous knowledge with information it is permitted to learn according to the current security policy.
Security against the perfect attacker A Per does not imply security against all attackers.Consider program P 4 below, which differs from P 3 only in the final command, which outputs variable a to channel C instead of b.Indeed, this program is insecure against attacker A 2 -only with level C, which remembers only the second observed event and whose knowledge suddenly improves from the set of all possible initial input environments to only those input environments where the first element of input stream w(A) matches the observed output.
Although security against perfect attacker A Per does not imply security against all attackers, security against some attackers does imply security against other attackers.Specifically, given some some set of attackers {A j } j∈J , if a program is secure against A j for all j ∈ J, then the program is also secure against an attacker that combines the knowledge of all A j .That is, the program is also secure against an attacker whose knowledge equals the intersection of the knowledge of A j for all j ∈ J.
Theorem 2. Let {A j } j∈J be a set of attackers, and for all j ∈ J, let c be secure against attacker A j with level .Let A be an attacker such that for all initial input environments w and traces t such that c, m init , w, init ⇓ (t, ) we have Then c is secure against attacker A with level .
Proof: By induction on the length of t.The base case t = is trivial.Suppose c, m init , w, init ⇓ ((t • α), ).By security of A j we have Thus we have k(c, A, , A(t Theorem 2 implies that if a program is secure against A i-only with level for all possible values of i, then c is secure against many other attackers with level , including the perfect attacker A Per , and all bounded memory attackers A last-j for all j.Theorem 3.For all commands c, if for all i, c is secure against A i-only with level , then c is secure against attacker A Per with level .
Proof: The knowledge of A Per is the intersection of {A j -only } j∈N .The result follows immediately by Theorem 2.
Theorem 4. For all commands c, if for all i, c is secure against A i-only with level , then for all j, c is secure against attacker A last-j with level .
Proof: Let j be fixed.Suppose c, m init , w, init ⇓ ((t • α), ).We need to show that the knowledge Consider the set of attackers A consisting of the A i-only attackers that record the j most recent events, and the latest event α.More precisely, From the definition of knowledge of attackers, we can show that the knowledge of A last-j after trace t has been emitted is the same as the intersection of the knowledge of all attackers in A. Intuitively, this is because they both know about the last j events.
Moreover, the knowledge of A last-j after trace t • α has been emitted is no more precise than the the intersection of the knowledge of all attackers in A. Since A last-j remembers the last j events, while A collectively remembers the last j + 1 events.
By Theorem 2 and the security of A i-only for all i, we have

Combining these equations gives us
as required.
These results (Theorems 2, 3, and 4) simplify both security reasoning and security enforcement.It allows both a system developer and an enforcement mechanism to consider the security of a program just with respect to attacker A i-only for all i: a set of simple attackers that are easy to understand.Security against attackers A i-only will imply security for a large and practical set of attackers.
However, security against all A i-only does not imply security against all attackers.For example, Figure 3 shows a program and an attacker A insec such that the program is secure against A i-only with level for all possible values of i, but is insecure against A insec .In an execution where the input from H is positive, then once A insec observes the output o(3, A), the attacker learns that the input was positive at a time when it is not permitted to learn this information.Intuitively, this is because the attacker's state machine does not record that it saw the event o(1, A), which would let it learn that the input was positive at an appropriate time.
Attacker A insec is, in some ways, being willfully stupid: it remembers observing the value 2 (by transitioning to state s 2 ) but ignores observing the value 1.It is not an attacker for which we particularly care whether our system is secure against.By contrast, we believe that the attackers A Per and A last-i are a useful, relevant, and realistic set of attackers, for which it is reasonable to ensure a system is secure against.Thus, enforcing security against A i-only is a worthwhile endeavor, even if it does not imply security against all attackers.
Characterizing such "willfully stupid" attackers is future work, as is the identification of a definitive class of attackers against which programs should be secure.

D. Progress-insensitive security
The definition of security given in Definition 1 is progress sensitive [3]: it accounts for knowledge the attacker may gain by observing progress of program execution.For example, consider the following program.
P 5 : output 0 to L; input x from H; while x > 0 do skip; output 1 to L An attacker observing channel L sees the second output event if and only if the while loop terminates.Since the loop guard depends on an input from channel H (which policy init does not allow to be learned by an observer of channel L), program P 5 is insecure according to Definition 1.
However, many practical enforcement techniques ignore information flow via the observation of progress, and enforce a definition of security that allows attackers to learn arbitrary information by observing progress.We present a progress insensitive version of the security definition to enable standard enforcement techniques.Indeed, the enforcement techniques we present in Section V enforce progress-insensitive security, defined below.
We define progress knowledge [3] as the set of initial input environments that could have led to the attacker's current state s, and can produce another event observable by the attacker (which may or may not change the attacker's state).
Progress knowledge is more precise than the attacker's knowledge, in that for all commands c, attackers A, attacker levels , and attacker states s, we have k(c, A, , s) ⊇ k + (c, A, , s).
We modify our previous definition of security to progressinsensitive security, which allows the attacker to learn that the program makes progress.That is, the attacker knowledge at each step is no more precise than the combination of the attacker's previous knowledge, the information the current security policy allows to be learned, and the knowledge that the program makes progress.The definition of progressinsensitive security differs from the definition of progresssensitive security (Definition 1) only in the replacement of k(c, A, , A(t)) with k + (c, A, , A(t)).
Definition 2 (Progress-insensitive security for input environment w).Command c is progress-insensitively secure against attacker A = (S A , s init , δ A ) with level for initial input environment w if for all traces t, events α, and policies such that c, m init , w, init ⇓ ((t • α), ) we have As with progress-sensitive security, the left-hand side of the equation is the attacker's new knowledge, and the righthand side of the equation provides a bound on how precise the attacker's knowledge is allowed to be.
Program P 5 satisfies progress-insensitive security (Definition 2) against A Per with level L for all input environments, but does not satisfy progress-sensitive security (Definition 1) against A Per with level L for an initial input environment w where the first element of w(H) is not positive.
The results of this section (specifically, Theorems 2, 3 and 4) hold for both progress-insensitive and progress-sensitive security.

E. Noninterference, declassification, and revocation
Noninterference [14] is a semantic security condition that requires that "high security" events do not interfere with, or affect, "low security" events.While there are many definitions of noninterference, most relevant here are knowledgebased definitions for interactive models (e.g., [3,4,9]).
The definitions of security, both progress sensitive and progress insensitive, generalize noninterference.More precisely, if the security policy never changes from the initial security policy, then progress-(in)sensitive security implies progress-(in)sensitive noninterference [2,3].
Declassification weakens noninterference, to allow some high-security information to be observed by low-security observers.There are at least two ways that declassification can be viewed or incorporated into our model.First, if the security policy changes from to , where ⊇ , then the new security policy allows more information flows.This can be viewed as a coarse-grained form of declassification, since previously disallowed information flows are now permitted.Second, finer-grained policies, described in Section VI, can be added into our model to allow partial flows between security levels.
Revocation occurs when security privileges are removed.In our model this corresponds to removing a flow that was previously allowed.Our security conditions allow previous knowledge of the attacker to persist, but allows new knowledge to be acquired only in accordance with the current security policy.

IV. FIRST-CLASS SECURITY POLICIES
Systems with dynamic security policies typically have a run-time representation of the security policy.For example, in a document management system that attempts to restrict which users may use which documents, users' permissions would be represented in a data structure, and the data structure examined and modified at runtime.
In this section, we extend our language to encode security policies at run time, which allows the program to inspect and manipulate security policies.The extension simplifies our semantics, requires no changes to the security definitions of Section III, and does not require complex enforcement mechanisms.
We encode the security policy in memory using a subset of the program variables.Let Λ be a function from L × L to variables, so that variable Λ( , ) encodes whether the current security policy allows information flow from to .For brevity, we write Λ , to denote variable Λ( , ).Flow is permitted from to if either = (since policies must be reflexive) or the current memory maps variable Λ , to a non-zero value.Given memory m, we write m for the security policy represented by m, defined as follows.
Definition 3 (Interpretation of the security policies m ).
The program may modify the current security policy by updating the variables Λ , .Thus, the encoding removes the need for a specialized syntax for policy changes, and setPolicy( ) can now be dropped from the language syntax.Moreover, the program can perform run-time tests to determine whether information flow is permitted from to simply by inspecting variable Λ , .
Program configurations c, m, w, no longer need to explicitly represent the current security policy , since it can be inferred from the current memory.Of course, given a semantics over configurations c, m, w that do not explicitly represent the current security policy, we can lift the semantics to those of Section II, and can thus carry over the security definitions of Section III with no modifications.
Consider the following example program where communication occurs between a server, abbreviated to S and a client, abbreviated to C, until the server chooses to terminate communication.This program satisfies both progress-sensitive and progress-insensitive security for attacker A i-only with any level for all i.The first line of this program establishes a security policy in which information can flow from C to S, and viceversa.The first input reads variable y from S. In the body of the loop, we input values from C into variable x.Because information can flow from S to C, the result of the expression x > y can also flow to C, and therefore the corresponding output statement is allowed.We input variable t from S, and use that value to update the security policy, possibly disallowing flow from S to C. However, before updating the security policy (Λ S,C := t) we output the value of t to C, so that C learns whether the security policy will change.This notification is needed; otherwise, when C observes the output of 0 at the end of the program, C would learn information about inputs from S at a time when it is not allowed by the current security policy.
As another example, suppose user U wants to upload content to web server W .Moreover, the server decides whether the user is allowed to upload content.Program P 7 models this scenario.
This program is both progress-sensitively and progressinsensitively secure against attacker A i-only with any level for all i.Variable Λ U,W is updated based on input from W .The conditional statement checks whether flow is allowed from U to W before transferring the file.This program is secure, because the upload occurs only when the information flow is permitted by the current security policy.

V. ENFORCEMENT
Sections III and IV present an expressive language and knowledge-based security conditions.The security conditions describe permitted information flow in the presence of dynamic security policies, even when the security policy is derived from runtime constructs of the program.
In this section we present both static and dynamic enforcement techniques for progress-insensitive security against attacker A i-only with any level, for all i.By the results of Section III, this implies progress-insensitive security against many other attackers, including the perfect attacker A Per and all bounded memory attackers A last-j .Progress-sensitive security can be enforced by more restrictive variations of these enforcement techniques (e.g., [3,27]).
Our enforcement techniques are adapted from existing information-flow control mechanisms.Like previous work, we track information flow using a security lattice [11].However, we use the powerset of security levels to track information flow, and check that information flows conform to the current enforced security policy only at program locations that generate observable events.
The absence of an event on a channel may reveal information to an observer.To control this information flow in the presence of dynamic security policies, we introduce a novel mechanism-channel context bounds-that tracks bounds on information flows arising from decisions to produce events on channels, a form of implicit information flow [11].
We note that, apart from channel context bounds, the enforcement mechanisms described in this section are largely standard.Soundness of these mechanisms is, nevertheless, an important contribution because it shows that dynamic security policies can be enforced using known techniques.Throughout the section we point out to a range of extensions that can improve accuracy of these techniques.

A. Static enforcement
We present a type system that enforces security for A i-only with any level, for all i.The type system is a mostly standard information-flow control security-type system (e.g., [28,36]).A security-type context Γ is a function from program variables to sets of security levels.Intuitively, if the value of program variable x at any point in the program's execution may reveal information about the initial input stream for channel , then ∈ Γ(x).We introduce channel context bounds ∆ that map channels to sets of security levels, and for each channel provide an upper bound on decisions to produce an observable event on that channel.Intuitively, if a decision to produce an input or output on channel may reveal information about the initial input stream for channel , then ∈ ∆( ).
Type judgment Γ, ∆, pc c means that command c is well-typed under security-type context Γ, channel context bounds ∆, and program counter levels pc, which is a set of security levels such that if information at level might have influenced control flow reaching command c, then ∈ pc.Program counter levels, in conjunction with channel context bounds, control implicit information flows [11]: information flow through the control flow structure of a program.
Inference rules for judgment Γ, ∆, pc c are presented in Figure 4. We write Γ(e) for the set of security levels of variables occurring in e: Γ(e) = {Γ(x) | x appears in e}.The rules are standard for security type systems except for the use of channel context bounds and the use of sets of security levels to track information flows.We explain these differences in more detail below.Powerset of security levels.We use sets of security levels to track information flow instead of taking upper bounds of security levels.This is because the security policy, which provides an ordering over security levels, may change during execution, and thus it is difficult to determine statically an "upper bound" of a given set of security levels.By tracking information flow using sets of security levels, we avoid needing to commit to any particular security policy at the time of analysis.At program points that may produce observable events on channel (i.e., input and output commands), we compute a set of security levels that is an upper bound on the information that the event may reveal (∆( ) for input statements, and ∆( )∪Γ(e) for output statements).For every security level in the upper bound we check that is allowed to flow to level at that program point, using the function may-flow ( , ), described below.
Static approximation of runtime security policy.As in security-type systems with dynamic security levels (e.g., [15,16,25,34,37]), we use a static analysis to track which information flows are permitted at a given program point.Instead of conflating this analysis with the type system, we assume that this analysis is specified separately, and the results of the analysis are available via the function may-flow ( 1 , 2 ).Note that the analysis needs to be flow sensitive, and we assume the function may-flow ( 1 , 2 ) takes as an implicit argument the program point for which we are querying the analysis results.This could be made explicit by adding labels to all program points (e.g., [26]).The static approximation of the runtime security policy is used to check information flow only at observable events: input and output commands.We assume that this analysis is sound: at a given program point, for some security levels 1 and 2 , if may-flow ( 1 , 2 ) is true, then in any execution, whenever that program point is reached, we have ( 1 , 2 ) ∈ , where is the current security policy in the configuration at the queried program point.Since the policy is interpreted from the current memory, this implies that the current value in variable Λ 1, 2 is non-zero.Thus, the analysis could be implemented as a standard constant propagation analysis.
Channel context bounds.We use channel context bounds to track and control information flow arising from the decision to perform an input or output.Channel context bounds restrict the contexts in which channels may be used.Consider the following program.
This program inputs a value from channel A, and, if that value is positive, outputs 1 to channel B. Information flow is then disallowed from A to B, and the value 2 is output on channel B. Suppose that the first event an attacker with level B sees is o(2, B).At that time, the attacker learns that the input from A was not positive, and thus learns information about A at a time when it is not permitted, violating security.Observation of event o(2, B) informed the attacker that event o(1, B) did not occur.We track this information flow using channel context bounds: ∆( ) is an upper bound on the information that may be learned by the occurrence or non-occurrence of any event on channel .It is a superset of the program counter levels at all input and output events on that channel.The use of channel context bounds in our type system ensures that insecure program P 8 above does not type-check.
The type system enforces progress-insensitive security against attacker A i-only with any level, for all i.
Theorem 5 (Soundness of type system).For all commands c, security levels , and i ∈ N, if there exists a securitytype context Γ and a channel context bounds ∆ such that Γ, ∆, ∅ c then c is progress-insensitively secure against attacker A i-only with level for all input environments w.
Proof sketch: Let w be an initial input environment, and let i be fixed.Suppose c, m init , w, init ⇓ ((t•α), ).If the length of t is greater than or equal to i, then let i be the security policy enforced when the ith event was emitted, and let Low = { | ( , ) ∈ i }.We can show that for any w ∈ [w] i , executions of c from initial input environments w or w will execute in lockstep whenever the program counter is low (i.e., Low ⊇ pc), and for any variable x such that Low ⊇ Γ(x), x will have the same values in both executions-this is part of a standard securitytype soundness proof.Moreover, due to the channel context bounds, we can show that any control-flow decision that may affect whether an observable event occurs must be low: at any program point where an observable event on channel may occur, we have pc ⊆ ∆( ), and from the typing rule at the program point of the ith observable event, we have ∀ ∈ ∆( ).
i .Next, we show that the knowledge of the attacker is appropriately constrained.We proceed by induction on the length of t.All cases for which the length of t is not equal to i − 1 are trivial, since Suppose the length of t equals i − 1.Now we need to show Suppose this is not the case.Then there is some w is the same starting from w as from w.The typing rules for input and output events require that α = α, giving a contradiction.
The type system presented here assumes a security-type context Γ that describes the levels of information that may be found in variables at any point in the program's execution.This context could be specified in advance, or could be inferred using a standard type inference algorithm.The type system could easily be adapted to a more precise flowsensitive security-type system [17,18].

B. Dynamic enforcement
Dynamic information-flow monitors (e.g., [3,12,19]) control the flow of information in a system by monitoring the system execution, and intervening when necessary.We describe a purely dynamic information-flow monitor [30] based closely on the monitor of Askarov and Sabelfeld [3].
To enforce progress-insensitive security, we need to define configurations and inference rules for monitored execution of program.A monitored configuration has the form ( c, m, w , st), where c, m, w is a program configuration (where the memory encodes the current security policy), and st is a monitor state.A monitor state is a stack of sets of security levels, and is used to track implicit information flows.The monitor state is analogous to the program counter levels pc used in the security-type system.We extend our original program semantics to issue monitor events to the monitor for assignments, branching, input and output.The monitor can decide whether to accept or reject a monitor event based on the current monitor state.A monitored configuration makes a transition only when the monitor event is accepted by the monitor.When the event is not accepted, program execution halts.This extension of the semantics follows the presentation of Askarov and Sabelfeld [3]. Figure 5 presents the monitor rules.
Monitored events, ranging over β, are: a(x, e) that indicates assignment to variable x of expression e, b(e) that indicates branching on expression e, f which corresponds to a join point after executing one of the branches, i(x, ) that is input to variable x on channel , and o(e, ) that is output of expression e on channel .The semantics of commands is augmented with a marker command end that is invoked upon reaching a join point.
As in the security-type system, we assume a securitytype context Γ and channel context bounds ∆.The monitor ensures that Γ and ∆ are bounds on the information that may be learned by examining the values of variables and performing input and output.That is, a value that may reveal information about the initial input stream w( ) may only be stored in variable x if ∈ Γ(x).In Figure 5, we write st for the union of all elements of the stack st.Recall that a stack element is a set of security levels.The set st describes which security levels could have influenced control flow reaching the current program point.
Interestingly, to check whether information flow is permitted from to , the monitor must inspect the current security policy m .Such inspection may reveal sensitive information, since it depends on the value of variable Λ , , which may reveal information about levels Γ(Λ , ).However, the resulting information channel cannot be magnified [4].
In dynamic enforcement, unlike static enforcement, Γ and ∆ need to be available at runtime.We call such executions Γ, ∆-monitored executions.This also requires lifting the definitions of knowledge and progress knowledge to be parameterized over Γ and ∆.Using these definitions of knowledge it is straightforward to lift the definition of progress-insensitive security to Γ, ∆-monitored progressinsensitive security.
Monitored transitions satisfy the rule c, m, w −→ α c , m , w st −→ β st ( c, m, w , st) −→ β α ( c , m , w , st ) We overload the notation for ⇓ , and write ( c, m, w , st) ⇓ (t, ) to denote that trace t is emitted on channel when starting from configuration ( c, m, w , st), and is the policy when the last event of t is emitted.In particular, if the last event is α and it is emitted by a transition ( c , m , w , st ) −→ β α ( c , m , w , st ) then = m in the above definition.The definition of attacker knowledge for monitored executions also reflects that transitions are monitored and A(t) = s} Note that the definition of knowledge is implicitly parametrized over Γ and ∆.
Soundness of the dynamic enforcement states that monitored executions satisfy the lifted progress-insensitive security for attacker A i-only with any level, for all i.
Theorem 6 (Soundness of dynamic enforcement).For all commands c, security levels , input environments w, security-type contexts Γ, channels contexts bounds ∆, and i ∈ N, it holds that Γ, ∆-monitored executions of c satisfy progress-insensitive security against attacker A i-only with level for input environment w.
Proof sketch: The structure of the proof follows the one of Theorem 5. Let w be an initial input environment, and let i be fixed.Suppose ( c, m init , w , ε) , such that ( c, m init , z , ε) ⇓ (q, ), and trace q contains at least i events.We show that the two executions, producing traces t • α and q are in lockstep whenever the monitor stack levels are low, i.e.Low ⊇ ( st), and for any variable x such that Low ⊇ Γ(x), x will have the same values in both executions.
Moreover, because of channel context bounds and constraints enforced on the i-the event, it must be that existence of the i−th event depends only on low information.
Next, similarly to the proof of Theorem 5, we can show that the knowledge of the attacker is appropriately constrained.

VI. EXTENSIONS
Our language-based model for information security in the presence of dynamic security policies is simple, expressive, and can be enforced using practical information-flow control techniques.In this section we highlight the simplicity by

A. First-class security levels
We add security levels as first-class values to the language, and extend the type system of Section V-A to enforce progress-insensitive security for this new language.This increases the expressiveness of the language, bringing it closer to realistic systems that represent and manipulate both security levels and security policies at run time.
The addition of first-class security levels does not change either the observational model or the definitions of security.We believe that this supports our design choice in the observational model and definitions of security: the addition of a security-relevant language feature changes just the enforcement mechanisms.
We extend the language to allow values to include security levels ∈ L, and add expression e 1 flows-to e 2 to test whether flow is permitted between levels.We extend input and output commands to specify the channel using arbitrary expressions.Figure 6 presents the modified syntax.
Language semantics remain the same, modulo extending the set of values to include security levels, and changing the evaluation of input and output commands to evaluate the channel expression.Definitions of attacker knowledge, progress knowledge, and progress-sensitive and progressinsensitive security remain unchanged.
The following program demonstrates the increased expressiveness of the language.Provided the security policy allows the appropriate flows, the program inputs a security level x from A, reads a value from channel x, and echoes it to channel B. We assume that expression e 1 flows-to e 2 evaluates to one if the current security policy permits information flow from e 1 to e 2 and zero otherwise.This program satisfies progress-sensitive and progress-insensitive security for attacker A i-only with any level, for all i.An attacker with level x upon observing the input event may learn the first input from channel A. Thus, the program must check that flow is permitted from A to x.An attacker with level B upon observing the output event may learn both the value input from x and that the first input from channel A was x.Thus the program must check that flow is permitted both from x to B and from A to B.
We can modify the type system of Section V-A to enforce progress-insensitive security for the extended language.The modified type system is described in Appendix A.

B. Fine-grained policies
The definitions of security and progress-insensitive security allow an attacker's knowledge to improve only in accordance with the current security policy.So far we have considered only coarse-grained security policies such that if ( , ) ∈ then an attacker at security level is allowed to learn everything about the initial input stream of channel .This is expressed in the security conditions by the set [w] of input environments that policy does not allow an attacker at security level to distinguish from the initial input environment w.
It is natural and straightforward to consider information flows at finer granularity.Equivalence relations over the initial input environments provide a flexible and expressive way of specifying what information an attacker is permitted to learn [13,31].
Let a fine-grained policy P = { ≈ } ∈L be a family of equivalence relations over initial input environments, indexed by ∈ L, and write [w] P for the equivalence class of input environment w under equivalence relation ≈ ∈ P .
Intuitively, fine-grained policy P describes for each security level what information an observer at level is allowed to learn.Fine-grained policies generalize security policies.
We modify language configurations to replace policies with fine-grained policies P , and assume there is some distinguished fine-grained policy P init used as the initial fine-grained policy for every execution.
The definition of security generalizes in the obvious way for fine-grained security policies, where equivalence class [w] P is used to restrict how the knowledge of an attacker is allowed to improve.We give the definition of fine-grained progress-sensitive security below; the definition of finegrained progress-insensitive security is similar, except that progress knowledge is used instead of attacker knowledge.Definition 4 (Fine-grained progress-sensitive security).Command c is fine-grained progress-sensitively secure against attacker A = (S A , s init , δ A ) with level for initial input environment w if for all traces t, events α, and finegrained policies P such that c, m init , w, P init ⇓ ((t • α), P ) Run-time encoding.In Section IV, policies were encoded in the run-time data structures of the language.The same approach can be taken with fine-grained policies.However, a suitable compact yet expressive encoding of the fine-grained policies must be chosen.One popular class of fine-grained policies is escape hatch expressions [22,29], which specify expressions over inputs that may be released to various security levels.Representing escape hatch expressions would require some runtime representation of the expressions, leading perhaps to the incorporation of first-class functions in the language, or of an explicit representation of abstract syntax trees.
Enforcement.There are existing enforcement mechanisms for certain classes of fine-grained policies, such as securitytype systems (e.g., [29]) and information-flow monitors (e.g., [3,20]).These mechanisms can be adapted to enforce finegrained progress-sensitive security by modifications similar to those described in Section V. To wit, checks that information flow conforms to policy should be performed at the program locations that generate observable events, and otherwise information flow should be tracked without any assumptions as to which policy is currently enforced.

VII. RELATED WORK
Broberg and Sands define flow locks [6][7][8] which specify conditions when information may flow between security levels.A flow lock may be explicitly opened or closed by a program, enabling or disabling information flow between levels.As such, flow locks allow for the dynamic updating of security policy.The semantic security condition for flow locks is knowledge based and quantifies over attackers with different observational abilities (which is analogous to our quantification over output channels ).The type system is of similar precision to ours.The key distinction between flow locks and this work is the semantic security condition: we consider security with respect to attackers with different abilities, while the work on flow locks is only concerned with perfect recall attackers.We believe that this is a crucial step forward in knowledge-based semantic security conditions.Such conditions are intended to restrict what an attacker learns, and when.Since learning is about change in knowledge, one must consider how the knowledge of different attackers change with observations: an attacker with perfect recall may not learn anything new from an observation, but the same observation may allow a more realistic weaker attacker to learn confidential information.
Hicks et al. [16] consider dynamic updating of information-flow policies.They permit arbitrary updates to the security policy, and introduce the semantic security condition noninterference between updates, which requires that the program satisfies a form of noninterference between any two consecutive updates to the security policy.There is no security guarantee across security updates.By contrast, our semantic security condition provides a guarantee across arbitrary updates.They enforce their security condition using nonstandard mechanisms, including permission tags, a form of type coercion between security levels that are inserted into execution only in accordance with the current policy, but may be reduced at any time.By contrast, our choice of observational model and security condition allows us to use simple adaptations of standard information-flow control mechanisms to enforce security.We adapt the enforcement mechanisms to delay checking of permitted information flows until the production of observable events.
The RX programming language [34], by Swamy et al., extends the policy update work of Hicks et al. [16] to make it more practical.They represent security policies using owned roles, derived from the RT role-based trustmanagement frameworks [21].They identify the problem of transitive flows, which inadvertently allow information flows that are permitted by neither the old nor new policy.They prevent transitive flows by using a transactional mechanism to ensure that if the security of a program fragment depends upon flow allowed by the current security policy, then those portions of the current security policy are not modified until the fragment finishes execution.Our static enforcement mechanism does not exhibit any transitive flows, but a transactional mechanism would potentially enable the may-flow (•, •) analysis to be more precise.
RX uses metapolicies to control information that may be revealed through policy updates.This is needed because policies are not first class in RX.Our model does not require metapolicies since the program is able to query and manipulate the security policy using standard program constructs (see Section IV).This justifies our design choice of cleanly separating the run-time behavior of the language from security policies: the definition of security and the semantics of security policies depend on the run-time behavior of programs, but not vice versa.
The Jif programming language [25] represents security principals at run time, and allows security principals to dynamically delegate their authority to other principals.Since delegation between security principals defines the security policy, Jif allows dynamic security updates.Broberg and Sands [8] encode Jif's Decentralized Label Model [24] in flow locks, and thus provide a semantic security condition for Jif.We believe that this work, provides a promising alternative approach to modeling Jif's run-time representation of security principals, and providing a semantic security condition for Jif that includes reasoning about the different abilities of different principals.
Grabowski and Beringer [15] consider an object-oriented language in which the enforced security policy may differ between executions of the same program.They do not consider the security policy changing during program execution.Security levels are first-class values in their language.To enforce noninterference, they use a security-type system with dependent types in which the runtime security policy is approximated statically (by static reasoning about the result of run-time tests of the security policy).Dependent types allow the security type of variables to be expressed in terms of dynamic security levels, similar to the dependent type system extension described in Section VI-A.Their type system allows locations storing security levels to be updated, although the security level stored in a location may only be raised to a more restrictive level, with respect to the security policy in force at run time.Our dependent type system also allows mutable locations to appear in security types.
Zheng and Myers [37] consider a lambda calculus with first-class security levels and a dependent security-type system.They assume that the security policy enforced at run time is statically known.However their type system, which enforces noninterference in the presence of security-typed variables, can also enforce noninterference when the runtime security policy is statically unknown.Unlike Grabowski and Beringer, they do not allow mutable locations to appear in security types.
As discussed in Section III-E, dynamically updatable security policies can enable a coarse-grained form of declassification, in which all flows between two security levels are permitted (possibly temporarily) after being previously disallowed.Other work has considered coarse-grained declassification.Mantel and Sands [23] present a language in which a more permissive security policy is used when control flow is within a downgrading command.Their semantic security condition is bisimulation-based, and the intuition is that in each step, information flows according to the current security policy.Almeida Matos and Boudol [1] also present a language where lexical scope enables more flows with a bisimulation-based security condition.Information flow from security level A to security level B is allowed within the scope of a flow A ≺ B in c command.
Balliu et al. [5] point out to the connection of the setbased definitions of attacker knowledge (that our definition is an instance of) to the epistemic account of knowledge.We believe that our intuition on security in the presence of dynamic policies also applies to when information flow policies are expressed using temporal epistemic logic; formal development of such result may provide for an interesting and fruitful future research direction.

VIII. CONCLUSION
We have presented a simple, elegant, and extensible model for reasoning about information security in the presence of dynamic security policies.We use an extensional knowledge-based semantic security condition, which can be enforced using adaptations of standard information-flow control techniques, in a language that permits arbitrary changes to the security policy.
The semantic security condition is straightforward and intuitive: an attacker should learn information only in accordance with the current security policy.The semantic security condition is parameterized on an attacker, and a program may be secure for a powerful attacker, yet insecure for a weaker attacker.We identify a class of simple attackers such that if a program is secure against all members of this class, the program is secure against many more attackers, including the most powerful possible attacker, and attackers with bounded memory.We present mechanisms that enforce security for this class of simple attackers, and thus also enforce security for a useful and realistic set of attackers.
The language can be easily extended with expressive security-relevant features, such as run-time representation of the security policy, first-class security levels, and finegrained security policies, without significant change to the semantic security condition.
We believe that this language-based model provides a promising platform on which to build practical systems with strong information security guarantees.e ∈ S. Also, the evaluation of e may reveal information, and so the rule requires S ⊆ S, where S is the set of level expressions for e.The channel context bounds must be an upper bound for the decision to perform any input or output, and so for all security levels ∈ values(e), we must have pc ⊆ ∆( ), where values(e) is a conservative approximation of possible security levels that e could evaluate to at this program point.Finally, an observer of channel e observes that an input event occurred, potentially allowing the observer to infer both that the command executed, and the value of expression e.Thus, for all ∈ values(e), all e ∈ ∆ ∪ S and all ∈ all -values(e ), flow must be allowed from to , where all -values(e ) is a conservative approximation of possible security levels that e could evaluate to at any program point.
Note that while we consider possible evaluations of expression e at just the queried program point (values(e)), we must consider possible evaluations of expressions e at any point in the program's execution (all -values(e )), since expressions e are taken from type information, and the type system is flow insensitive.
Execution of an output command output e 1 to e 2 reveals information to an observer of channel e 2 , including that the command executed, the value of both expression e 1 and e 2 .The typing rule for output commands requires that that may-flow ( , ) is true for all ∈ values(e 2 ), all e ∈ ∆ ∪ S 1 ∪ S 2 and all ∈ all -values(e ).
The modified type system enforces security for the extended language.
Theorem 7.For all commands c, security levels , and i ∈ N, if there exists a security-type context Γ and a channel context bound ∆ such that Γ, ∆, ∅ dep c then c is progressinsensitively secure against attacker A i-only with level .
The proof of Theorem 7 is similar in structure to the proof of Theorem 5.
Program P 9 is well-typed under a security-type context Γ such that Γ(x) = {A} and Γ(y) = {x, A}, and provided may-flow (A, x) evaluates to true at command input y from x, and may-flow (x, B) and may-flow (A, B) both evaluate to true at the output command.

P 2 :
Allow info flow from Nuclear to U Output keywords(nuke 1 ) to U . . .Disallow info flow from Nuclear to U Output keywords(nuke 1 ) to U

P 4 :
input a from A; input b from B; setPolicy( AB→C ); output a + b to C; setPolicy( B→C ); output a to C During execution of P 4 , the knowledge of A Per is identical to the knowledge of A Per during an execution of P 3 .Thus, program P 4 is secure against A Per with attacker level C.But intuitively the program is insecure!It outputs variable a to channel C even though the current security policy does not allow information flow from A to C.

Figure 3 .
Figure 3. Example program and attacker A insecof attacker A last-j after trace t • α has been emitted (k(c, A last-j , , A last-j (t • α))) is no more precise than the knowledge of the attacker after t has been emitted (k(c, A last-j , , A last-j (t))) combined with what the attacker is permitted to know ([w] ).Consider the set of attackers A consisting of the A i-only attackers that record the j most recent events, and the latest event α.More precisely, A = {A i-only | (|t| − j + 1) ≤ i ≤ |t| + 1}.

P 6 :
Λ C,S := 1; Λ S,C := 1; input y from S; while Λ S,C = 0 do input x from C; output x > y to C; input t from S; output t to C; Λ S,C := t; output 0 to C

Figure 6 .
Figure 6.Modified language syntax for first-class security levels

P 9 :
input x from A; if A flows-to x then input y from x else skip; if (x flows-to B and A flows-to B) then output y to B else skip

Figure 7 .
Figure 7. Typing rules for dependent type system