One of the principal security issues of the internet in the past two decades has persistently been the deceptively straightforward challenge of safeguarding user accounts. At present, individuals possess accounts on numerous websites with a multitude of passwords, resulting in significant quantities of breaches as various websites, often managed by individuals who lack expertise in the intricate aspects of cryptography and web security, become targets of remarkably adept hackers. Additionally, users frequently confront the dilemma of remembering countless passwords, either by simplifying them or using identical ones for all – often resulting in quite unfortunate consequences. Over the years, a collection of makeshift solutions has indeed emerged, such as utilizing one’s email account as a universal safeguard, and “password manager” tools like Lastpass, albeit at a steep price: these methods either retain a significant part of the inherent complexity of password-based access or endow centralized corporations with excessive control over your online existence.
Numerous advocates are pushing to eliminate remove passwords, but the pressing question remains: what do we substitute them with? Various concepts have been proposed, ranging from “one master password to govern them all” to smartphone validation, specialized hardware devices, biometrics, and a myriad of multi-factor M-of-N frameworks. However, even these advanced setups have generally proven to be application-specific: many banking institutions now provide a dedicated access device for logging into your account, but that device, if deemed secure, cannot be used for accessing your email. Generally, it appears that the challenge of effectively managing user access control while minimizing the risks of key loss and theft is intricate enough that it cannot be definitively resolved, thus the optimal method is to cultivate a thriving free market of solutions and enable each user to select the options that suit them best. Nevertheless, facilitating this requires detaching the “access control solutions” sector from the “services” sector. In other words, this is precisely what we are, to a considerable extent, not accomplishing currently.
The device used to access my UBS bank account. Remind me, why can’t I also utilize this to protect my domains on Namecheap?
So how can we achieve that? The initial step is to imbue a well-considered application of the ultimate abstraction: Turing-complete code. Instead of, at the protocol level, permitting users to set a password, or offering a predetermined selection of providers, or even a standard that depends on interfacing with a server of the user’s choosing, allow access rules to be defined in code capable of executing within a deterministic virtual machine (where the EVM serves as an excellent starting point). The code may encompass digital signature validations employing any cryptographic technique (thus offering future compatibility with quantum-resistant cryptography), possibly involving keys stored on the user’s computer, keys directly generated from a password, keys secured on a hardware device, or any arbitrary policy that includes any mix of the aforementioned. This approach allows for innovation in access-control systems without any requirement for websites (or other systems requiring authentication) to modify anything in response to new developments. Moreover, the mechanism conveniently enables organizations to implement the framework using multi-user access controls immediately, with no further requirement for interoperability.
The subsequent stage involves Turing-complete operation-dependent code. For numerous applications, it is essential to authorize certain users to perform specific actions but not others; for example, you might wish to permit a sysadmin to modify the IP address that a domain name directs to, but not to sell the domain entirely. To address this, the abstraction must transform. A straightforward “Turing-complete code as a signature” setup may take the following structure:
VM(code, server-provided nonce ++ signature) ?= 1
Where VM signifies a virtual machine executing code, taking a server-supplied nonce and a signature as its inputs, while the verification check determines whether or not the output equals 1. A straightforward illustration of code that could be integrated is an elliptic curve digital signature.verifier. To facilitate diverse authorization prerequisites based on the operation, you desire:
VM(code, server-supplied nonce ++ operation_data ++ signature) ?= 1
A signature would need to accompany every action the user intends to perform (this has the advantage of offering undeniable, third-party-verifiable proof that an action was sanctioned); the activity data (think of the function name and the parameters encoded in an Ethereum-style ABI) would be included as an argument for the virtual machine, and the signature must encompass both the nonce and the activity data.
This brings you quite far, but in certain situations, it may not be sufficient. A straightforward scenario is: what if you wish to grant someone authorization to withdraw minor amounts of money but not significant amounts, i.e., a withdrawal ceiling? In such a case, the challenge you must address is clear: what if someone constrained by a withdrawal limit of $100 attempts to circumvent it by merely running a script to withdraw $90 repeatedly? To resolve this, you require a more intelligent withdrawal limit; specifically, something akin to “maximum $100 per day.” Another obvious situation is key revocation: if a key becomes compromised or lost, you need to replace it, and you want to ensure that the world is aware of the policy shift so attackers cannot impersonate you under the former terms.
To surpass this final barrier, we must progress one level deeper: we require Turing-complete operation-dependent stateful policies; in other words, operations should be capable of altering the state of the policy. And this is where not only cryptography but specifically blockchains come into play. Naturally, you could merely have a central server oversee everything, and many individuals are completely comfortable with placing their trust in a centralized server, but blockchains hold considerable value here due to their enhanced convenience, provision of a credible narrative of impartiality, and ease of standardization. Ultimately, since it would be quite detrimental to innovation to permanently opt for “one blockchain to govern them all,” what we aim to standardize is a mechanism through which users can download modules to support any blockchain or centralized solution as they choose.
For blockchain-based applications, enforcing a stateful policy directly on the blockchain seems logical; there is no need to involve yet another category of intermediaries, and individuals can start implementing it immediately. The abstraction of an “account” that Ethereum provides makes it exceptionally straightforward to engage with this methodology: if your application accommodates straightforward users possessing private keys, it also applies to virtually all types of individual, multiparty, hardware-driven, military-grade, or any other policy users may conceive in the future.
For alternative applications, users might desire privacy, both in the operations that alter state and even regarding the nature of their policy at any given time. For this rationale, you may find a solution like Hawk preferable, where the blockchain still safeguards the process but, thanks to the innovations of zero-knowledge-proof technology, remains oblivious to what is being secured; before the implementation of Hawk, simpler forms of cryptography such as ring signatures may suffice.
Other Applications
Account security represents the primary and most fundamental application of the concept of code as policy, but there are additional ones. A straightforward example is that of a domain name registry. Onename, one of the well-known “decentralized name registry” services, is currently planning to introduce a feature where top-level domains can establish fee policies for subdomains based on the count of letters, consonants, and vowels. This is advantageous, but certainly economically unattractive: there are undoubtedly hundreds of attributes beyond letters, consonants, and vowels that can impact the price of a domain name, and individuals might even wish to explore different registration methods such as various types of auctions.
Once more, an even more attractive solution would be to apply straightforward modularity: allowing individuals to create their own namespace in stateful Turing-complete code. If you are engaging in this on a platform where stateful Turing-complete code exists, you can simply permit an address to govern a subdomain, and then, voilà, you already support stateful Turing-complete subdomain policies. This encapsulates the essence of object-oriented programming: expose an interface, and allow other objects, which can possess arbitrarily intricate internal code, to fulfill that interface.
Another example is private stock trading. Especially in the context of privately owned companies, stock trading is not, and cannot be entirely free and unrestricted in the manner that cryptocurrency trading is; companies often wish to implement restrictions such as:
- Providing employees with shares and permitting them to sell only after a designated period
- Mandating new shareholders be approved by existing shareholders, potentially with limitations on how many shares can be held by that specific owner
- Mandatory buyback processes
- Limiting the maximum rate at which stocks are sold (i.e., withdrawal limits) or necessitating waiting periods or bestowing certain other holders a right of first refusal
Certainly, you can develop a private blockchain-based stock trading platform for one client, and implement the restrictionsthat a particular client desires. However, what if other clients require varying restrictions? You might as well address the issue early on, at least within the “core application layer”, and resolve it definitively by… allowing each distinct stock, represented as a sub-currency, to have restrictions defined as dynamic Turing-complete code.
This capability can be represented in the “token” API by expanding it, for example, as follows:
- getMinimumBalance(account): retrieve the minimum balance that an account may possess at the present time
- getMaximumBalance(account): retrieve the maximum balance that an account may possess at the present time
In summary, applications do not possess policies; applications interact with entities (user accounts, currencies, etc.), and entities have policies. Alternatively, more concisely:

Are you developing a blockchain-centric financial derivatives application, and someone requests you to add functionality for voting among multiple data feed providers instead of just one? Do not consider it; rather, simply set one data feed provider address, and let users formulate their own policies; the advantage is that whatever code they utilize or compose, they’ll be able to employ to more securely provide data feeds for the arbitration dapp as well. Are you constructing a DNS system, and someone is suggesting you include support for specific auction types for subdomains? Refrain from doing it at the root DNS level; instead, permit subdomains to act as addresses, and allow users to create their own auction algorithms; whatever algorithms they create, they’ll be able to apply to their registry for decentralized chat usernames too.
This illustrates the advantage of abstraction: account security policy development can evolve into a standalone area of study, and any new solutions can be immediately implemented universally. Some individuals will prefer to rely on a third party; others will desire multi-signature authorization among five of their personal devices, while some will want a key for themselves with the option for three out of five friends to collaborate to reset the key to a new one. Some will seek an access policy stating that, if they don’t conduct any transactions within twelve months, they are considered deceased, and a lawyer will gain access to facilitate their will’s execution – for all of their digital assets. Additionally, some will prefer a policy that grants one key complete control for applications that identify as low-security, but two out of three keys for applications that define themselves as high-security. Designing a name registry pricing policy can also become self-contained – as can digital asset ownership restriction policies, a domain that would captivate everyone from small and large traditional corporations to community-oriented DAOs. And that embodies the strength of dynamic Turing-complete code.