class
Amber::Configuration::CredentialsDirectory
- Amber::Configuration::CredentialsDirectory
- Reference
- Object
Overview
Reads a credentials directory: one file per credential, where the file name is the credential name and the file contents are its value.
This is the layout systemd's LoadCredential= and
LoadCredentialEncrypted= produce in $CREDENTIALS_DIRECTORY. The
reader takes the directory path as an argument and reads files only;
the application's configuration decides where the path comes from.
Contents are kept byte for byte, including any trailing newline, so
write credential files without one (printf '%s' "$secret").
Each read opens the directory once and then lists, checks and opens
every entry relative to that open directory, so replacing the directory
or one of its parents with a symlink part way through cannot redirect
the read. Each credential file is opened without following a final
symlink and without blocking, then checked through the open descriptor,
so an entry swapped for a symlink or a FIFO after it was listed is
rejected rather than read or waited on. Reads are capped per file and
per read. Windows has no credentials directory, and the reader raises
Amber::Exceptions::CredentialsDirectoryUnsupported there.
Every failure raises a named Amber::Exceptions::CredentialsError
subclass whose message names the directory and the credential, never
its value. The reader does not log.
struct AppCredentials
include YAML::Serializable
property secret_key_base : String = ""
property database_url : String? = nil
def initialize
end
end
directory = Amber::Configuration::CredentialsDirectory.new("/run/credentials/app.service")
directory.read_credential("secret_key_base") # => "..."
directory.read # => {"database_url" => "...", "secret_key_base" => "..."}
directory.read_into(AppCredentials) # => AppCredentials(@secret_key_base="...", ...)
Defined in:
amber/configuration/credentials_directory.crConstant Summary
-
DEFAULT_MAXIMUM_FILE_SIZE =
64_i64 * 1024 -
The default cap on a single credential file: 64 KiB.
-
DEFAULT_MAXIMUM_TOTAL_SIZE =
(1_i64 * 1024) * 1024 -
The default cap on everything one read takes from the directory, counting file names and contents: 1 MiB, systemd's own total limit.
-
LARGEST_ALLOWED_SIZE =
Int32::MAX.to_i64 -
The largest cap either size limit accepts.
-
MAXIMUM_LINK_TARGET_SIZE =
4096 -
The longest symlink target the reader looks at (PATH_MAX).
-
MAXIMUM_NAME_SIZE =
255 -
The longest credential name a file system accepts (NAME_MAX).
Constructors
-
.new(directory : String, maximum_file_size : Int64 = DEFAULT_MAXIMUM_FILE_SIZE, maximum_total_size : Int64 = DEFAULT_MAXIMUM_TOTAL_SIZE)
Raises
ArgumentErrorwhen a cap is negative or aboveLARGEST_ALLOWED_SIZE.
Class Method Summary
-
.mapping_of(values : Hash(String, String)) : YAML::Nodes::Mapping
Builds a YAML mapping of double-quoted scalars from credential values, so a credential whose contents are
nullortruestays that text in aString?field. -
.section_from(type : T.class, values : Hash(String, String), directory : String) : T forall T
Builds a section of type from credential values keyed by YAML key.
Instance Method Summary
- #directory : String
- #maximum_file_size : Int64
- #maximum_total_size : Int64
-
#read : Hash(String, String)
Reads every credential in the directory into a hash keyed by file name.
-
#read_credential(name : String) : String
Reads one credential by name.
-
#read_credential?(name : String) : String | Nil
Reads one credential by name, or returns nil when no file has that name.
-
#read_for(type : T.class) : Hash(String, String) forall T
Reads the credentials that type declares: one file per YAML key of the type, skipping keys with no file.
-
#read_into(type : T.class) : T forall T
Reads the credentials that type declares and builds the typed section.
Constructor Detail
Raises ArgumentError when a cap is negative or above
LARGEST_ALLOWED_SIZE.
Class Method Detail
Builds a YAML mapping of double-quoted scalars from credential values,
so a credential whose contents are null or true stays that text in
a String? field. :nodoc:
Builds a section of type from credential values keyed by YAML key. :nodoc:
Instance Method Detail
Reads every credential in the directory into a hash keyed by file name.
Raises Amber::Exceptions::CredentialsDirectoryTooLarge when the file
names and contents together exceed #maximum_total_size.
Reads one credential by name.
Raises Amber::Exceptions::CredentialPathTraversal when name is not a
plain file name, such as ../other_service/key,
Amber::Exceptions::CredentialNotFound when no file has that name, and
Amber::Exceptions::CredentialsDirectoryTooLarge when the name and
contents exceed #maximum_total_size.
Reads one credential by name, or returns nil when no file has that name.
Reads the credentials that type declares: one file per YAML key of the type, skipping keys with no file. Other files in the directory are neither read nor checked.
Raises Amber::Exceptions::CredentialPathTraversal when the type
declares a key that is not a plain file name.
Reads the credentials that type declares and builds the typed section.
Each file name maps to the field with that YAML key. Files with no matching field are ignored; fields with no file keep their default.