|cryptex(5)||File Formats Manual||cryptex(5)|
Unlike other archive formats (e.g. tar(1), cpio(1), etc.), the content of a cryptex is not intended to be merged to a filesystem root. Conventionally, archives are merged to the root filesystem so that the operating system can discover new or updated content at a set of pre-determined paths that are relative to the filesystem root. For example, the user's chosen shell may discover executables in /usr/bin, and therefore new executables must be merged into that location in order for the shell to discover them.
However, as Darwin has more aggressively defended its operating system bits from tampering (e.g. via the Signed System Volume), it has become necessary to begin recognizing other content roots that are separate from the system but otherwise writeable by the user. For example, the shell may also discover executables in /usr/local/bin, which resides on the data volume rather than the signed and immutable system volume.
But these extra roots essentially force a single package of software to "break itself up" in order to be installed. Shell tools must be copied to one location, dynamic libraries to another, daemons to still another, etc. Once this is done, all provenance for the software is more or less lost unless the operating system employs complex monitoring and tracking of filesystem events.
Instead of extracting content and merging it to another filesystem, a cryptex is instead mounted at a randomly-chosen location when the system boots. Its content may then be examined by any subsystems which are interested in discovering content from cryptexes. In other words, subsystems must explicitly be taught about the possible existence of cryptex content, and the usefulness of cryptexes is directly proportional to the number of subsystems that agree to look for their contents.
This scheme maintains the structure of a software package as a single entity that is always handled as such. Prior to mounting the filesystem, the operating system can verify that the archive file itself has not been tampered with by taking a measurement of it and comparing to a known-good measurement before agreeing to mount it.
Views are distinguished by root directories in the filesystem, and each the view in which a piece of content resides has implications about the intended scope of that content. Defined views are
|Application||-tag -width -indent -compact Pa ./ Pa ./opt Pa ./usr/local||Content which is private to the cryptex and should not be discovered by other subsystems|
|Platform||-tag -width -indent -compact Pa ./System Pa ./usr||Content which is published to the broader platform and should be discovered by other subsystems|
cryptex subsystem provides these
barriers by requiring a priori knowledge of a type of
content before it can be published for discovery to the broader operating
system. Because the
cryptex subsystem maintains
complete control over where cryptexes are published and available in the
filesystem, other subsystems cannot simply crawl the filesystem and reliably
discover content they are interested in. These subsystems must ask the
cryptex subsystem for a type of
content of a specific name within a
specific view. The path to a given piece of content is
constructed from this (view, type, name) tuple. Put
another way, rather than inferring information about content type and scope
from a filesystem path, cryptexes construct the filesystem path from
information about content type and scope.
|CONTENT TYPE||DIRECTORY||DESCRIPTION||IMPLEMENTATION NOTES|
|Shell tool||bin||Binaries directly executed by the user in a shell||Automatic discovery not implemented, though the CRYPTEX_PATH environment variable will provide a location which can be added by the user to his or her shell search path|
|Dynamically-linked library||lib||Shared libraries which may be mapped as executable into an already-executing process||Libraries in the Application view are discovered and respected by the linker such that processes within a cryptex can use libraries within that same cryptex|
|System executable||libexec||A binary which is used by other programs and not meant to be directly executed by the user||Not implemented|
|Daemon||Library/LaunchDaemons||A launchd.plist 5 which describes and defines a launchd 8 service||Daemons in the Application view are discovered and bootstrapped automatically when the cryptex is mounted|
|Agent||Library/LaunchAgents||A launchd.plist 5 which describes and defines a user-specific launchd 8 service||Not implemented|
|Manual page||share/man||A man 1 page which documented a component within the cryptex||Not implemented|
|Application||Applications||A GUI application which is directly launched by the user||Not implemented|
|Cocoa framework||Library/Frameworks||A specially-packaged dynamically-linked library which may include headers, resources, and versioning in a single directory structure||Not implemented|
|Platform||Dynamically-linked library||libfoo.dylib||-tag -width -indent -compact Pa ./usr/lib/libfoo.dylib Pa ./System/lib/libfoo.dylib|
|Application||System executable||barbaz||-tag -width -indent -compact Pa ./libexec/barbaz Pa ./opt/libexec/barbaz Pa ./usr/local/libexec/barbaz|
All paths to a resource are considered exactly equivalent, and if the cryptex is built with different pieces of content at equivalent paths, the one returned by a query for that tuple is undefined.
|LIBRARY PATH||VIEW||EXAMPLE POLICY|
|./usr/lib/libfoo.dylib||Platform||Any process may link|
|./lib/libbar.dylib||Application||Only processes within the same cryptex may link|
Nothing about the current implementation's behavior should be considered stable, and implementation needs have been largely driven by the needs of the Security Research Device program. The details of these behaviors should be expected to change.
|4 September, 2020||Darwin|