@@ -137,6 +137,27 @@ theorem partial_authorize_decision_is_sound
137137 unfold IsExplicitlyPermitted IsExplicitlyForbidden
138138 exact .intro h_permit h_not_forbid
139139
140+ /-- Trivial composition of the first two soundness theorems directly relating
141+ the decision of partial authorization and subsequent re-authorization.-/
142+ theorem partial_re_authorize_decision_eq
143+ {schema : Schema}
144+ {policies : List Policy}
145+ {req : Request}
146+ {es : Entities}
147+ {preq : PartialRequest}
148+ {pes : PartialEntities}
149+ {response : TPE.Response}
150+ {decision : Decision} :
151+ TPE.isAuthorized schema policies preq pes = Except.ok response →
152+ isValidAndConsistent schema req es preq pes = Except.ok () →
153+ response.decision = some decision →
154+ (response.reauthorize req es).decision = decision
155+ := by
156+ intro h₁ h₂ h₃
157+ have h₄ := partial_authorize_decision_is_sound h₁ h₂ h₃
158+ have h₅ := reauthorize_is_sound h₂ h₁
159+ simp [h₅, h₄]
160+
140161/-- All policies reported as erroring after partial authorization will appear in
141162the set of erroring policies after concrete authorization. -/
142163theorem partial_authorize_erroring_policies_is_sound
@@ -218,9 +239,9 @@ theorem partial_authorize_allow_determining_policies_is_sound
218239 · rw [←hp₂] at hpid
219240 exact hpid
220241
221- /-- If the result of concrete authorization is `deny`, then all `forbid`
222- policies satisfied after partial authorization are determining policies .-/
223- theorem partial_authorize_deny_determining_policies_is_sound
242+ /-- We can prove a stronger theorem for `satisfiedForbid`:
243+ because `forbid_trumps_permit` any satisfied forbid policy will always be determining .-/
244+ theorem partial_authorize_satisfied_forbid_is_determining
224245 {schema : Schema}
225246 {policies : List Policy}
226247 {req : Request}
@@ -230,45 +251,51 @@ theorem partial_authorize_deny_determining_policies_is_sound
230251 {response : TPE.Response} :
231252 TPE.isAuthorized schema policies preq pes = Except.ok response →
232253 isValidAndConsistent schema req es preq pes = Except.ok () →
233- (Spec.isAuthorized req es policies).decision = .deny →
234254 response.satisfiedForbids ⊆ (Spec.isAuthorized req es policies).determiningPolicies
235255:= by
236- intro h₁ h₂ h_deny
256+ intro h₁ h₂
237257 simp only [TPE.isAuthorized] at h₁
238258
239- have h_deny' : ¬ ((satisfiedPolicies Effect.forbid policies req es).isEmpty = true ∧ (satisfiedPolicies Effect.permit policies req es).isEmpty = false ) := by
240- grind [Spec.isAuthorized]
241- simp only [Spec.isAuthorized, Bool.and_eq_true, Bool.not_eq_eq_eq_not, Bool.not_true, h_deny', ↓reduceIte]
242-
243259 cases h₃ : List.mapM (λ p => ResidualPolicy.mk p.id p.effect <$> evaluatePolicy schema p preq pes) policies <;>
244- simp [h₃ ] at h₁
260+ simp only [bind_pure_comp, h₃, Except.map_ok, Except.map_error, Except.ok.injEq, reduceCtorEq ] at h₁
245261 rename_i rps
246262 rw [List.mapM_ok_iff_forall₂] at h₃
247263 subst response
248264
249- simp [isAuthorized.isAuthorizedFromResiduals, isAuthorized.satisfiedPolicies,
250- satisfiedPolicies, satisfiedWithEffect, satisfied, Bool.and_eq_true,
251- decide_eq_true_eq, Set.subset_def, ← Set.make_mem, List.mem_filterMap,
252- ResidualPolicy.satisfiedWithEffect, ResidualPolicy.satisfied, Residual.isTrue,
253- Option.ite_none_right_eq_some, forall_exists_index, and_imp]
265+ simp only [isAuthorized.isAuthorizedFromResiduals, isAuthorized.satisfiedPolicies, Set.subset_def,
266+ ← Set.make_mem, List.mem_filterMap, ResidualPolicy.satisfiedWithEffect,
267+ ResidualPolicy.satisfied, Residual.isTrue, Bool.and_eq_true, beq_iff_eq,
268+ Option.ite_none_right_eq_some, Option.some.injEq, forall_exists_index, and_imp]
254269 intro pid rp hrp heff hs hpid
255270 split at hs <;> try contradiction
256271
257272 have ⟨p, hp₁, hp₂⟩ := List.forall₂_implies_all_right h₃ rp hrp
258273 cases hp₃ : evaluatePolicy schema p preq pes <;>
259- simp only [hp₃, Except.map_error, Except.map_ok, reduceCtorEq, Except.ok.injEq] at hp₂
274+ simp only [hp₃, Except.map_error, Except.map_ok, reduceCtorEq, Except.ok.injEq] at hp₂
275+ rename_i ty hr r
260276
261- exists p
262- and_intros
263- · exact hp₁
264- · rw [←hp₂] at heff
265- exact heff
266- · rename_i ty hr r
277+ have ha : Spec.evaluate p.toExpr req es = .ok (.prim (.bool true )) := by
267278 replace hr : r = .val (.prim (.bool true )) ty := by grind
268279 have ha := partial_evaluate_policy_is_sound hp₃ h₂
269280 simp only [hr, Residual.evaluate] at ha
270281 exact to_option_right_ok' ha
271- · rw [←hp₂] at hpid
272- exact hpid
282+
283+ suffices h : pid ∈ satisfiedPolicies Effect.forbid policies req es by
284+ have hd : IsExplicitlyForbidden req es policies := by
285+ exists p
286+ and_intros <;> grind [satisfied]
287+ replace hd : (Spec.isAuthorized req es policies).decision = .deny :=
288+ forbid_trumps_permit _ _ _ hd
289+ grind [Spec.isAuthorized]
290+
291+ simp only [satisfiedPolicies, satisfiedWithEffect, satisfied, Bool.and_eq_true, beq_iff_eq,
292+ decide_eq_true_eq, ← Set.make_mem, List.mem_filterMap, Option.ite_none_right_eq_some,
293+ Option.some.injEq]
294+ exists p
295+ and_intros
296+ · exact hp₁
297+ · simpa [←hp₂] using heff
298+ · exact ha
299+ · simpa [←hp₂] using hpid
273300
274301end Cedar.Thm
0 commit comments