Jo – a statically typed language with fine-grained capabilities

liufengyun1 pts0 comments

Introducing Jo — Secure Programming for the AI Era | Jo Programming Language

Skip to content

Appearance

MenuReturn to top

Introducing Jo — Secure Programming for the AI Era ​<br>Today we are introducing Jo , a statically typed programming language where side effects are denied by default and authority must be granted explicitly, through fine-grained capabilities checked by the compiler.<br>Modern systems execute plugins, call third-party services, run user-defined workflows, and increasingly ask AI agents to generate and execute code. The security question is no longer only "is this program correct?" It is also:<br>How do we restrict an untrusted program to only the fine-grained capabilities it has been granted?

Jo is designed to make fine-grained permission confinement a property enforced by the type system, at the level of precision real systems need: a specific directory, a single API host, a read-only interface, or only the database rows belonging to the current user.<br>The Problem: Ambient Authority ​<br>Most mainstream languages make powerful authority available by default. A piece of code can usually reach for the filesystem, environment variables, network, reflection, process APIs, or foreign-function interfaces unless a runtime sandbox stops it.<br>That model is convenient, but it is hard to audit. If you want to run a third-party function and guarantee that it can only query a narrow API, not read files or call the network, the language itself usually gives you little help. You end up relying on containers, permissions, code review, convention, or runtime isolation.<br>Jo takes a different route: authority is represented by explicit capabilities, and those capabilities can be as narrowly scoped as the application requires. The compiler tracks which capabilities code may use, so confinement is expressed in interfaces and types rather than hidden in runtime configuration.<br>Capability-Based Programming ​<br>In Jo, capabilities are ordinary parameters. They can be passed, refined, substituted, and restricted. A function that has not received a capability cannot use it.<br>Here is an example:<br>jodef foo() = println "foo" // inferred capability: stdout<br>def bar() = foo() // inferred capability: stdout

def qux() receives IO.stdout = println "qux" // explicit capability: stdout

def main =<br>allow none in bar() // error: stdout not allowed<br>allow IO.stdout in bar() // OK<br>with IO.stdout = s => pass in qux() // redirect output<br>The compiler checks capability flow through the call graph. If a function needs IO.stdout, that requirement is visible and controllable. If a call site says allow none, then no hidden authority can slip through.<br>This gives Jo the convenience of implicit context without the security cost of ambient globals.<br>Why This Matters for AI-Generated Code ​<br>AI-generated code makes the authority problem even more acute. If an agent writes a function for your application, you may want it to analyze data and produce a summary, but not access the filesystem, call arbitrary HTTP endpoints, inspect environment variables, or query other users' records.<br>Jo's approach is to grant only the capabilities the code should have:<br>jo// API library: compiled without FFI support<br>interface OrdersApi<br>def query(lastDays: Int): List[Order]<br>end

param ordersApi: OrdersApi

// AI-generated code<br>def aiMain(): Unit receives ordersApi, IO.stdout =<br>val orders = ordersApi.query(30)<br>summarize(orders)<br>The framework can implement OrdersApi using a real database, but expose only a user-scoped, read-only view to the untrusted code. The AI-generated function does not receive raw database access. It does not receive network access. It does not receive filesystem access. The type checker enforces that boundary before the program runs.<br>This is the core idea behind Jo: make authority confinement a programming model.<br>CONFINED WORLDno FFI · confined libs onlyJo Standard LibraryList · Map · Option · Result · …Interface Libraryinterface OrdersApi { … }defer def aiMain(): UnitAI-Generated CodeaiMain() implements contractdepends ondepends onTRUSTED WORLDFFI enabled · auditedPlatform RuntimeFFI · syscalls · network · filesystemHarnessUserScopedOrders(userId, db)frameworkMain()depends ondepends on--linkThe Two-World Architecture page describes this model in detail, and Secure Language Design covers the language facilities — capability parameters and authority attenuation — that make confinement practical.<br>For a concrete example, see the data-query agent demo, which shows how an agent can ask flexible questions over a database while being statically restricted to the current user's data.<br>A Language, Not Just a Policy System ​<br>Jo is also intended to be pleasant as a general-purpose language. It combines object-oriented and functional programming with a compact syntax, type inference, classes, interfaces, algebraic data types, pattern matching, and context parameters.<br>For example, Jo has reusable pattern predicates:<br>jopattern Positive: Partial[Int] = case x if x >...

code stdout language capabilities authority programming

Related Articles