Skip to content

Commit 70dad88

Browse files
committed
refactor(code-samples): 📝 Turn code samples into snippets for "Object Capabilities" directory
1 parent dc86c15 commit 70dad88

6 files changed

+60
-58
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
primitive NetAuth
2+
new create(from: AmbientAuth) =>
3+
None
4+
5+
primitive DNSAuth
6+
new create(from: (AmbientAuth | NetAuth)) =>
7+
None
8+
9+
primitive UDPAuth
10+
new create(from: (AmbientAuth | NetAuth)) =>
11+
None
12+
13+
primitive TCPAuth
14+
new create(from: (AmbientAuth | NetAuth)) =>
15+
None
16+
17+
primitive TCPListenAuth
18+
new create(from: (AmbientAuth | NetAuth | TCPAuth)) =>
19+
None
20+
21+
primitive TCPConnectAuth
22+
new create(from: (AmbientAuth | NetAuth | TCPAuth)) =>
23+
None
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
use "net"
2+
3+
class MyTCPConnectionNotify is TCPConnectionNotify
4+
let _out: OutStream
5+
6+
new iso create(out: OutStream) =>
7+
_out = out
8+
9+
fun ref connected(conn: TCPConnection ref) =>
10+
_out.print("connected")
11+
conn.close()
12+
13+
fun ref connect_failed(conn: TCPConnection ref) =>
14+
_out.print("connect_failed")
15+
16+
actor Connect
17+
new create(out: OutStream, auth: TCPConnectAuth) =>
18+
TCPConnection(auth, MyTCPConnectionNotify(out), "example.com", "80")
19+
20+
actor Main
21+
new create(env: Env) =>
22+
Connect(env.out, TCPConnectAuth(env.root))
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
actor Connect
2+
new create(out: OutStream, auth: TCPConnectAuth) =>
3+
TCPConnection(auth, MyTCPConnectionNotify(out), "example.com", "80")
4+
5+
actor Main
6+
new create(env: Env) =>
7+
try Connect(env.out, TCPConnectAuth(env.root)) end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ponyc --safe=files:net:process my_project

docs/object-capabilities/derived-authority.md

Lines changed: 6 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -13,36 +13,15 @@ In Pony, the `Main` actor is created with an `Env` object, which holds the unfor
1313
Here is a program that connects to example.com via TCP on port 80 and quits:
1414

1515
```pony
16-
use "net"
17-
18-
class MyTCPConnectionNotify is TCPConnectionNotify
19-
let _out: OutStream
20-
21-
new iso create(out: OutStream) =>
22-
_out = out
23-
24-
fun ref connected(conn: TCPConnection ref) =>
25-
_out.print("connected")
26-
conn.close()
27-
28-
fun ref connect_failed(conn: TCPConnection ref) =>
29-
_out.print("connect_failed")
30-
31-
actor Connect
32-
new create(out: OutStream, auth: TCPConnectAuth) =>
33-
TCPConnection(auth, MyTCPConnectionNotify(out), "example.com", "80")
34-
35-
actor Main
36-
new create(env: Env) =>
37-
Connect(env.out, TCPConnectAuth(env.root))
16+
--8<-- "derived-authority-delegating-and-restricting-authority.pony"
3817
```
3918

4019
The `Main` actor authorizes the `Connect` actor by passing a `TCPConnectAuth` token created from the ambient authority token in `env.root`. The ambient authority token is unforgeable since the `AmbientAuth` constructor is private and the only existing instance is provided by the runtime itself.
4120

4221
The `Connect` actor uses this derived authority when it creates a TCP connection:
4322

4423
```pony
45-
TCPConnection(auth, MyTCPConnectionNotify(out), "example.com", "80")
24+
--8<-- "derived-authority-delegating-and-restricting-authority.pony:18:18"
4625
```
4726

4827
The `TCPConnection` requires an authority as first parameter, and since the compiler checks that the correct type was passed, this guarantees that a `TCPConnection` can only be created by an actor holding the required authorization.
@@ -58,13 +37,7 @@ The first parameter of the `TCPConnection` constructor has the type `TCPConnectA
5837
Now imagine we don't trust the `Connect` actor, so we don't want to provide it with more authority than needed. For example, there is no point in granting it filesystem access, since it is supposed to do network things (specifically, TCP), not access the filesystem. Instead of passing the entire `AmbientAuth` (the root of all authority), we "downgrade" that to a `TCPConnectAuth` (the most restrictive authority in `net`), pass it to the `Connect` actor, and have that pass it to the `TCPConnection` constructor:
5938

6039
```pony
61-
actor Connect
62-
new create(out: OutStream, auth: TCPConnectAuth) =>
63-
TCPConnection(auth, MyTCPConnectionNotify(out), "example.com", "80")
64-
65-
actor Main
66-
new create(env: Env) =>
67-
try Connect(env.out, TCPConnectAuth(env.root)) end
40+
--8<-- "derived-authority-restrict-then-delegate-your-authority.pony"
6841
```
6942

7043
Now we are sure it cannot access the filesystem or listen on a TCP or UDP port. Pay close mind to the authority that code you are calling is asking for. Never give `AmbientAuth` to __any__ code you do not trust completely both now and in the future. You should always create the most specific authority and give the library that authority. If the library is asking for more authority than it needs, __do not use the library__.
@@ -80,35 +53,13 @@ As the package author, it is then our responsibility to realize that the minimal
8053
Let's have a look at the authorizations available in the standard library's `net` package.
8154

8255
```pony
83-
primitive NetAuth
84-
new create(from: AmbientAuth) =>
85-
None
86-
87-
primitive DNSAuth
88-
new create(from: (AmbientAuth | NetAuth)) =>
89-
None
90-
91-
primitive UDPAuth
92-
new create(from: (AmbientAuth | NetAuth)) =>
93-
None
94-
95-
primitive TCPAuth
96-
new create(from: (AmbientAuth | NetAuth)) =>
97-
None
98-
99-
primitive TCPListenAuth
100-
new create(from: (AmbientAuth | NetAuth | TCPAuth)) =>
101-
None
102-
103-
primitive TCPConnectAuth
104-
new create(from: (AmbientAuth | NetAuth | TCPAuth)) =>
105-
None
56+
--8<-- "derived-authority-authority-hierarchies.pony"
10657
```
10758

10859
Look at the constructor for `TCPConnectAuth`:
10960

11061
```pony
111-
new create(from: (AmbientAuth | NetAuth | TCPAuth))
62+
--8<-- "derived-authority-authority-hierarchies.pony:22:22"
11263
```
11364

11465
you might notice that this looks like a hierarchy of authorities:
@@ -120,9 +71,7 @@ where in this paragraph, ">>" means "grants at least as much authority as". In f
12071
This hierarchy is established by means of the constructor of the weaker authority accepting one of the stronger authorities, for example:
12172

12273
```pony
123-
primitive TCPAuth
124-
new create(from: (AmbientAuth | NetAuth)) =>
125-
None
74+
--8<-- "derived-authority-authority-hierarchies.pony:13:15"
12675
```
12776

12877
Where `TCPAuth` grants less authority than `NetAuth`. `NetAuth` can be used to create any of the derived authorities `DNSAuth`, `UDPAuth`, `TCPAuth`, `TCPListenAuth`, `TCPConnectAuth` whereas `TCPAuth` can only be used to derive `TCPListenAuth` and `TCPConnectAuth`.

docs/object-capabilities/trust-boundary.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ But we can do better than that.
1717
In Pony, you can optionally declare a set of _safe_ packages on the `ponyc` command line, like this:
1818

1919
```sh
20-
ponyc --safe=files:net:process my_project
20+
--8<-- "trust-boundary-safe-packages.sh"
2121
```
2222

2323
Here, we are declaring that only the `files`, `net` and `process` packages are allowed to use C-FFI calls. We've established our trust boundary: any other packages that try to use C-FFI calls will result in a compile-time error.

0 commit comments

Comments
 (0)