Overview

Safe references are opaque, orderable data items that can be used as a security-aware index into a data set.

Consider a library callbacks that enables other libraries to manage callback functions.

library Callbacks
{
    metadef callback:str->str. 
    // metadef callback_handle:...
    fn RegisterCallback (c:callback) -> callback_handle { 
        ... 
    }

    fn DeregisterCallback (h:callback_handle) { 
        ...
    }
}

The two functions, RegisterCallback and DeregisterCallback must work together, and do so securely. The library needs to be designed in such a way that the owner of the callback and only the owner of the callback is able to invoke and deregister it. So, what type does callback_handle need to be?

We could define it as a string or an integer or a binary blob. The problem is that doing so makes it possible for other components in the same application to reconstruct the handle if its value becomes known.

To avoid this possibility, we can use the SAFEREF domain. The MUFL evaluator guarantees that it is not possible to reconstruct an identical safe reference value a second time without having access to a variable that contains its original value. In other words, safe references may be passed around, but cannot be duplicated.

This concept is similar to capability-based programming (CBP), but in the context of database-like systems. In CBP, capability pointers represent function pointers. In MUFL, because functions, like any data, may be stored in dictionaries, the most convenient mechanism to implement capabilities is to simply enable opague ordered values to serve as keys.

Constructing Safe References

You can use the _new_safe_ref primitive function to construct a new safe reference. Once constructed, the value can be used as a key into a dictionary.

key is saferef = _new_safe_ref(). // construct a safe reference
dict is saferef->>str = (,). 
dict key -> "SECRET INFORMATION".

Safe references are implemented as 32-byte long strings of random bytes generated using the packet’s random number generator.

Important!: Because safe references are not forgeable, it is not possible to deserialize them, for example, in the context of passing arguments to a transaction. In other words, safe references cannot be passed as data between different ADAPT nodes. They can only be used to harden interfaces between ADAPT libraries that are part of the same application.