Skip to content

Commit e03a1ee

Browse files
Follow up to TPE auth theorems (#847)
Signed-off-by: John Kastner <jkastner@amazon.com>
1 parent 96ec37b commit e03a1ee

File tree

1 file changed

+51
-24
lines changed

1 file changed

+51
-24
lines changed

cedar-lean/Cedar/Thm/TPE.lean

Lines changed: 51 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -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
141162
the set of erroring policies after concrete authorization. -/
142163
theorem 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

274301
end Cedar.Thm

0 commit comments

Comments
 (0)