惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Vercel News
Vercel News
Y
Y Combinator Blog
H
Hackread – Cybersecurity News, Data Breaches, AI and More
The GitHub Blog
The GitHub Blog
N
Netflix TechBlog - Medium
MyScale Blog
MyScale Blog
F
Fortinet All Blogs
Microsoft Azure Blog
Microsoft Azure Blog
H
Help Net Security
C
Check Point Blog
博客园 - 聂微东
云风的 BLOG
云风的 BLOG
M
MIT News - Artificial intelligence
U
Unit 42
WordPress大学
WordPress大学
B
Blog
Last Week in AI
Last Week in AI
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
D
DataBreaches.Net
G
Google Developers Blog
T
The Blog of Author Tim Ferriss
Hugging Face - Blog
Hugging Face - Blog
IT之家
IT之家

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Designing Reliable Permission Models with Lean 4
Shrijith Ven · 2026-05-18 · via DEV Community

Hello, I'm Shrijith Venkatramana. I'm building git-lrc, an AI code reviewer that runs on every commit. Star Us to help devs discover the project. Do give it a try and share your feedback for improving the product.


Most authorization systems begin simple.

Then reality happens.

Over time:

  • more roles get added,
  • exceptions accumulate,
  • workflows become stateful,
  • permissions become inherited,
  • AI assistants start generating handlers and refactors,
  • and eventually nobody is fully certain what combinations are actually possible anymore.

This is where many discussions around “AI-generated code safety” become unsatisfying.

People often talk about:

  • better prompts,
  • more tests,
  • stronger reviews,
  • static analysis,
  • or safer languages.

Those help.

But there is another direction worth exploring:

What if some critical invariants were not merely tested, but mathematically enforced?

Not:

  • “the code probably works,”
  • or “the tests passed,”

but:

“certain invalid states are mechanically impossible.”

That is the interesting promise behind Lean.

And permission systems are one of the best places to start because:

  • humans understand them intuitively,
  • they are security-critical,
  • and they become surprisingly difficult to reason about once complexity grows.

This tutorial walks through:

  • installing Lean 4,
  • understanding the core mathematical ideas,
  • building a permission model,
  • proving security invariants,
  • intentionally breaking them,
  • and seeing how Lean prevents unsafe changes.

The goal is not academic theorem proving.

The goal is:

designing systems where important security assumptions become hard to accidentally violate.

1. Installing Lean 4

Lean 4 is unusual because it is simultaneously:

  • a programming language,
  • a compiler,
  • and a theorem prover.

Install it using elan.

Linux/macOS

curl https://raw.githubusercontent.com/leanprover/elan/master/elan-init.sh -sSf | sh

Enter fullscreen mode Exit fullscreen mode

Verify installation:

lean --version
lake --version

Enter fullscreen mode Exit fullscreen mode

2. Install the VSCode Extension

Install:

  • “Lean 4”

from the VSCode marketplace.

This gives:

  • live proof checking,
  • inline errors,
  • theorem goals,
  • and interactive feedback.

This interactivity matters a lot.

Lean is less like:

  • writing static code,

and more like:

  • continuously negotiating with a mathematical verifier.

3. Create a Lean Project

Create a project with Mathlib support:

lake new VerifiedPermissions math
cd VerifiedPermissions
code .

Enter fullscreen mode Exit fullscreen mode

Open:

VerifiedPermissions/Basic.lean

Enter fullscreen mode Exit fullscreen mode

This file will contain both:

  • executable programs,
  • and mathematical proofs about those programs.

That duality is the central idea behind Lean.

4. First Lean Program

Replace the file contents with:

def greet (name : String) : String :=
  s!"Hello, {name}"

#eval greet "world"

Enter fullscreen mode Exit fullscreen mode

Let’s unpack this carefully.

def

def greet

Enter fullscreen mode Exit fullscreen mode

def means:

define a function or value.

This is ordinary programming.

(name : String)

(name : String)

Enter fullscreen mode Exit fullscreen mode

This means:

  • the function accepts a parameter called name,
  • whose type is String.

Lean is statically typed.

But unlike many languages:

  • types in Lean are deeply connected to logic itself.

That becomes important later.

: String

: String

Enter fullscreen mode Exit fullscreen mode

This declares:

the function returns a string.

So mathematically:

greet : String → String

Enter fullscreen mode Exit fullscreen mode

Meaning:

  • greet maps one string into another string.

Functions in Lean are treated very mathematically.

:=

:=

Enter fullscreen mode Exit fullscreen mode

Means:

is defined as.

#eval

#eval greet "world"

Enter fullscreen mode Exit fullscreen mode

Actually runs the program.

This is important because Lean is not just:

  • a proof notation system,
  • or symbolic logic language.

It is executable.

5. A Small Verified Function

Now replace the file with:

def increment (x : Nat) : Nat :=
  x + 1

theorem increment_is_larger (x : Nat) :
  increment x > x := by
  exact Nat.lt_succ_self x

Enter fullscreen mode Exit fullscreen mode

This is where things become interesting.

You are no longer just writing code.

You are writing:

  • code,
  • and mathematical claims about the code.

6. Understanding the Mathematics Line by Line

Nat

Nat

Enter fullscreen mode Exit fullscreen mode

Means:

natural numbers.

So:

  • 0, 1, 2, 3…

Lean treats mathematics as native objects.

increment

def increment (x : Nat) : Nat :=
  x + 1

Enter fullscreen mode Exit fullscreen mode

This is an executable function.

Nothing unusual yet.

theorem

theorem increment_is_larger

Enter fullscreen mode Exit fullscreen mode

This changes everything conceptually.

You are no longer saying:

“I hope this property holds.”

You are saying:

“This property must be proven.”

And Lean will refuse to continue unless the proof is valid.

(x : Nat)

The theorem applies universally.

Meaning:

For every natural number x

Enter fullscreen mode Exit fullscreen mode

not:

  • “for tested examples,”
  • not “for likely inputs,”
  • but literally all possible values.

This is one of the biggest conceptual differences from testing.

Tests are existential:

These cases worked.

Enter fullscreen mode Exit fullscreen mode

Proofs are universal:

All valid inputs satisfy this property.

Enter fullscreen mode Exit fullscreen mode

increment x > x

increment x > x

Enter fullscreen mode Exit fullscreen mode

This is the claim being proven.

Meaning:

increment always returns a larger number.

:= by

:= by

Enter fullscreen mode Exit fullscreen mode

This begins a proof block.

You are now constructing evidence that the statement is true.

exact

exact Nat.lt_succ_self x

Enter fullscreen mode Exit fullscreen mode

This says:

use an existing theorem directly.

Nat.lt_succ_self is a theorem already known to Lean:

x < x + 1

Enter fullscreen mode Exit fullscreen mode

So Lean verifies:

  • your theorem,
  • by reducing it to already-proven mathematics.

7. Breaking the Proof Intentionally

Now change:

increment x > x

Enter fullscreen mode Exit fullscreen mode

to:

increment x < x

Enter fullscreen mode Exit fullscreen mode

You now claim:

increment makes numbers smaller.

Lean immediately rejects this.

This is the first important moment.

The theorem is not:

  • documentation,
  • comments,
  • or developer intent.

It is mechanically enforced logic.

8. Building a Permission Model

Now we move toward authorization systems.

Replace the file with:

inductive Role
| Guest
| User
| Admin

Enter fullscreen mode Exit fullscreen mode

9. Understanding inductive

This line introduces a very important mathematical idea.

inductive Role

Enter fullscreen mode Exit fullscreen mode

This defines a finite set of possible values.

Mathematically:

Role ∈ {Guest, User, Admin}

Enter fullscreen mode Exit fullscreen mode

This is powerful because:

  • impossible states cannot exist,
  • invalid roles cannot appear accidentally,
  • and all cases must be handled explicitly.

This already improves reliability substantially.

10. Defining Permissions

Now add:

def canDelete : Role  Bool
| Role.Guest => false
| Role.User => false
| Role.Admin => true

Enter fullscreen mode Exit fullscreen mode

This means:

canDelete maps a Role into a boolean

Enter fullscreen mode Exit fullscreen mode

or mathematically:

Role → Bool

Enter fullscreen mode Exit fullscreen mode

Meaning:

  • every role deterministically maps to a permission decision.

11. Why This Is Safer Than It Looks

Notice something subtle.

Lean forces all role cases to be handled.

If you later add:

| Moderator

Enter fullscreen mode Exit fullscreen mode

Lean immediately complains that:

  • canDelete is incomplete.

This is extremely valuable operationally.

In many production systems:

  • new authorization states get introduced,
  • old logic silently becomes incomplete,
  • edge cases appear months later.

Lean forces exhaustive handling.

That alone prevents many categories of policy drift.

12. Adding Security Invariants

Now add:

theorem guests_cannot_delete :
  canDelete Role.Guest = false := by
  rfl

theorem users_cannot_delete :
  canDelete Role.User = false := by
  rfl

Enter fullscreen mode Exit fullscreen mode

13. Understanding rfl

rfl

Enter fullscreen mode Exit fullscreen mode

means:

this is true by direct reduction.

Lean computes:

canDelete Role.User
→ false

Enter fullscreen mode Exit fullscreen mode

So the theorem becomes:

false = false

Enter fullscreen mode Exit fullscreen mode

which is trivially true.

14. Introducing a Security Bug

Now simulate a future refactor.

Change:

| Role.User => false

Enter fullscreen mode Exit fullscreen mode

to:

| Role.User => true

Enter fullscreen mode Exit fullscreen mode

Immediately:

users_cannot_delete

Enter fullscreen mode Exit fullscreen mode

fails.

This is where the practical value starts appearing.

The proof acts like:

  • a permanently active security assertion.

Not:

  • documentation,
  • not review guidelines,
  • not tribal knowledge.

An enforced invariant.

15. Why This Matters More with AI-Generated Code

The interesting part is not tiny examples like this.

The interesting part is what happens later when:

  • AI assistants generate handlers,
  • rewrite permission logic,
  • refactor workflows,
  • or modify state transitions.

The problem is no longer:

“Will the code compile?”

The problem becomes:

“Did the generated system preserve critical invariants?”

Formal models become interesting because:

  • implementations can change repeatedly,
  • while the invariants remain fixed and machine-checked.

16. What Lean Is Actually Buying

Lean does not magically create bug-free software.

What it can realistically provide is:

  • machine-checked invariants,
  • exhaustive handling of states,
  • prevention of silent policy drift,
  • stronger guarantees around transitions,
  • and continuous enforcement of critical assumptions.

That is a narrower claim than:

“formally verified applications.”

But it is also much more practical.

And for authorization-heavy systems, even small mechanically enforced guarantees can become surprisingly valuable over time.


*AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.*

Any feedback or contributors are welcome! It's online, source-available, and ready for anyone to use.


AI agents write code fast. They also silently remove logic, change behavior, and introduce bugs -- without telling you. You often find out in production.

git-lrc fixes this. It hooks into git commit and reviews every diff before it lands. 60-second setup. Completely free.

See It In Action

See git-lrc catch serious security issues such as leaked credentials, expensive cloud operations, and sensitive material in log statements

git-lrc-intro-60s.mp4

Why

  • 🤖 AI agents silently break things. Code removed. Logic changed. Edge cases gone. You won't notice until production.
  • 🔍 Catch it before it ships. AI-powered inline comments show you exactly what changed and what looks wrong.
  • 🔁 Build a