Centralized authentication configuration and storage for network-based resources
Draft version
.authrc
provides a generic and centralized configuration file for authentication credentials management and storage, that can be used by any application or service for network-based resources. It aims to be a standard adopted by the community
Current version: 0.1
Note that the specification is currently under active designing, which means that notorious changes can be done in a few future.
- Simple and easy to configure
- Centralized
- Locally stored
- Secure (encrypted passwords with solid symmetric ciphers)
- Full URI/URL supporting any network resource type
- Resource matching based on regular expressions or string matching
- Any type of application can easily support it
- Platform/language independent
- Support for oAuth?
- Support for
ini
format?
The file must always be named .authrc
.
This is important because it removes the ambiguity and helps to discover the file based on a standardized name.
The file content must be a well formed JSON
JSON is a general purpose well known data change information format. It is simple, easy to read, edit and parse.
Like .authrc
can be edited manually, it's necessary to prevent format ambiguity syntax.
The strict part of the JSON syntax is ideal because it prevents problems when the file is parsed and when it is edited manually: mmaybe opinionated, but it’s probably the better than formats like YAML
or ini
.
There is not a plan to support another format. Please, read the FAQ for more information
The general standard pretension is to have just a unique .authrc
file for the whole system,
however in some scenarios this is not the best choice or it’s simply impossible.
By default, the .authrc
file should be located at $HOME
or %USERPROFILE%
path directory,
but you can store it wherever you want.
Take into account that if you are using a non-global located file for specific purposes,
all stored hosts
values will override the global .authrc
config.
The file must be read and written using UTF-8 encoding
The .authrc
file search discovery algorithm should do what follows:
Try to find .authrc file on the current working directory
If it exists, read and parse it
If it doesn’t exist, fallback to $HOME
Try to find .authrc file in $HOME directory
If it exists, read and parse it
If it doesn’t exist, finish the process
The file must be a JSON object containing a set of
properties containing the Host
value and which implement the Host
config object.
{
"<hostValue>": <hostConfig>,
"<hostvalue>": <hostConfig>,
"<hostValue>": <hostConfig>
}
Here’s a basic file example
{
"my.host.org": { ... },
"my.server.org": { ... },
"10.0.0.1": { ... }
}
The host
value must be a string
.
The string
can contain any type of value, but usually you should define a full or partial URI-like format
Aditionally, a valid regular expression is supported like the host
value.
To define a host like regular expression, you need to wrap the host
value with /
characters.
The hosts matching must be always case-insensitive.
regulars expressions
support was added in order to avoid redundancy in your .authrc
and to support more complex host
definitions for particular cases.
You should be careful when it comes to defining a host-like regular expression
.
It is recommended that you define as more explicit regex
as you can in order
to prevent ambiguity during the host matching process,
for example avoiding the wild card helper operator (*.)
Here there are some valid host
values examples
http://my.server.org
my.server.org:8443
my.server.org/some/resource
amazing.host
10.0.0.1
https://172.16.0.1:8080
ftp://ftp.server.org
git://my.repo.org/path/to/repo.git
/http[s]?://(\w.).server.org/
/[a-z0-9]+.server.org/
In some scenarios you need to have different authentication credentials for the same
hostname
, for example if there are a couple of services running in different ports.
In order to prevent incorrect use of authentication credentials for bad network
resources, it is recommended to define the host
value in the more explicit way as
possible in order to prevent issues when the host
matching algorithm tries to discover
the appropriated credentials in your authrc
file.
Imagine you have a service to download resources via HTTP and a Git repository,
both running on my.server.org
, both of them are accesible via HTTP, under the same resolution hostname
and the same TCP port, but the only difference between them is that they are accessible
under different server path names, so your .authrc
should look like:
{
"http://my.server.org/downloads": { ... },
"http://my.server.org/git": { ... }
}
Note this is a draft version, improvement and contributions are welcome
There are two different matching processes, one for regex-like
and another one for string-like
matching.
The string-like
matching algorithm uses both partial comparison of individual parts of
an URI schema and, secondly, a more deep matching based on a string
comparison letter by letter, according with the proposed algorithm
An O(ND) Difference Algorithm by Eugene W. Myers
What follows explains the detailed process of how the matching host algorithm must be implemented:
0.
Get all the existent hosts in `.authrc` file (first level object properties)
If there is no hosts, exit the process
1.
Parse the search string to match like a valid URI
If it is not a valid URI, assume the existent value is the hostname
Store the parsed value
2.
Iterate all the existent properties
2.1
Check if the `host` string value is a regex-like expression (starts and ends with '/')
If it is a regex expression, validate it
If it is not valid, discard the host
If it is valid, continue
If it is NOT a regex-like string value
Parse the string like a valid URI (if it is not a valid URI, assume the existent value is the hostname)
If it is valid and the value is not empty
Then extract the `hostname`
Performs a string comparison between hostnames values
If the hostnames matches, set like a valid host
If not match, discard the host
If it is invalid, discard the host
2.2
Iterate each valid host, matching with the search string to match
If it is a regex, test it with the search string to match
If the regex test succeed
Set the host as matched
If the regex test fails
Discard the host
If it is NOT a regex
Parse like a valid URI
Parse host string value like a valid URI
Extract the port and protocol form the URI in both
Performs a comparison between port and protocol values
If at least one value is equal
Set as matched host
If there is not an equality
Discard the host
If port or protocol values do not exists in any processed hosts
Set all as matched (it is required a deep comparison)
Continue with the next host
2.3
Get the list of the current matched hosts
If there is not any matched host from 1.2 process
Get the valid hosts from 1.1 process
Discard the regex type host values
Performs a string comparison by letter for each host (using An O(ND) Difference Algorithm)
Get the host with minor letters differences returned by the algorithm
Mark it as the found host
If there is one matched host from 1.2 process
Mark it as the found host
If there is more than 1 matched host from 1.2 process
Discard the regex type host values
Get the valid host from 1.2 process
Performs a string comparison letter by letter for each host (using An O(ND) Difference Algorithm)
Get the host with minor letters differences returned by the algorithm
Mark it as the found host
3.
Finally, return the matched host value
The host
config object it’s where the authentication credentials will be stored.
Basically it is an object with two properties: username
and password
Each host
object must implement one of the following interfaces
interface HostAuthRaw {
attribute String username;
attribute String password;
}
Implementation example
{
"my.server.org": {
"username": "john",
"password": "$sup3r-p@sSw0rd"
}
}
interface HostAuthEncrypted {
attribute String username;
attribute HostConfigPassword password;
}
The password property must implement at least one of the following interfaces
Encrypted password with explicit cipher algorithm
interface HostPasswordCipher {
attribute String value;
attribute String cipher;
}
Encrypted password with default cipher algorithm
interface HostPasswordEncrypted {
attribute String value;
attribute Boolean encrypted;
}
Encrypted password with environment variable value store
interface HostPasswordEncryptedEnviroment {
attribute String envValue;
attribute String cipher;
}
Encrypted password with environment variable decryption key value store
interface HostPasswordEncryptedEnviromentKey {
attribute String value;
attribute String cipher;
attribute String envKey;
}
Implementation examples
{
"my.server.org": {
"username": "john",
"password": {
"value": "41b717a64c6b5753ed5928fd8a53149a7632e4ed1d207c91",
"cipher": "aes256"
}
}
}
Environment variable encrypted password store
{
"my.server.org": {
"username": "john",
"password": {
"envValue": "MY_ENCRYPTED_PASSWORD",
"cipher": "aes256"
}
}
}
Environment variable decryption key store
{
"my.server.org": {
"username": "john",
"password": {
"value": "41b717a64c6b5753ed5928fd8a53149a7632e4ed1d207c91",
"envKey": "MY_SECRET_DECRYPT_KEY",
"cipher": "aes256"
}
}
}
In this case, it should use the default algorithm AES128
{
"my.server.org": {
"username": "john",
"password": {
"value": "41b717a64c6b5753ed5928fd8a53149a7632e4ed1d207c91",
"encrypted": true
}
}
}
See examples/ for full featured example files
Password encryption must be supported by all the implementations.
The encrypted value, as it is defined above, can be stored in .authrc
at the password.value
property,
or stored in an environment variable at the password.envValue
property
Only well-tested symmetric ciphers algorithms are supported. Choose whatever you prefer :)
- AES 128 (if not defined, must use this by default)
- AES 256
- Camellia 128
- Camellia 256
- Blowfish
- CAST
- IDEA
- SEED
All the above ciphers algorithms are well supported by OpenSSL
The encryption/decryption process must be always done using UTF-8 encoding
All the password encrypted values must be post-encoded as hexadecimal
value string
The encryption/decryption process for all the ciphers algorithms must be performed using the CBC operation mode.
There is no plan to support initialization vectors, it just adds an unnecessary level of complexibility
First of all, if you use .authrc
, it is assumed that your machine is a secure environment
.authrc
proposal does not guarantee any type of additional level of security, it all depends
on your personal security prevention and how you store your decryption keys
.authrc
was created to be practical in the first place while security comes after
If you are paranoic and you want to add an additional level of security, you can encrypt/decrypt the whole file by your own way.
- Avoid store passwords in plain format, use encryption instead
- For environment variable decryption key, define it by prompt input at each new shell session
- You should be careful about how and where you store your password decryption keys
- Set your
authrc
file permissions to be only readable by you - Use different ciphers and different keys for shared passwords across different hosts
- You should avoid that your
.authrc
be tracked by a SCM (unless you know what you are doing)
Here is more information about password strength and recommendations
Currently looking for Java, Python, Ruby and C/C++ implementations
- Is it planned to encrypt the whole .authrc file?
Not at the moment, but the idea is open. However, you can encrypt/decrypt the whole file yourself adding the additional desired security level
- Is it planned to support another file format?
At the moment only JSON format is supported, however in a future it will support more.
If you have a good one in mind for this proposal, please share it :)
- How can I do if I have the same credentials for more than one host?
You should copy the whole credentials.
Maybe host
alias will be supported in a near future. Proposals for this are welcome.
- How my application can use the
.authrc
file?
You can use any of the current official specification implementations for your programming language or make your own.
- Is there a command-line support?
Yes. Most of the implementations should have a full featured CLI support for basic .authrc
file manipulation
See the implementations section to see which are available.
- Can host names values be full
regex
compatible?
Yes. Just be careful about escape characters or bad formed expressions and keep in mind to define your expression as more explicit as possible
You can check you expression here
- Is the host matching algorithm robust?
Probably it is not the best solution to the problem, but it is a first good solution.
The current algorithm was well tested with some different URIs types and schemas and it works as expected, however, more test cases are required.
Note that this still a draft specification. If you have a proposal to improve it, please feel free to make it
- What about the 160, 192, 224 bits symmetric keys support?
As you probably already know, in a practise world there is not very usual to use different encryptions keys than 128 or 256 bits.
128 bits key length provides a strong level of security, but if you are paranoid you can use 256 bits key length.
- Can I encrypt the user name?
No. Really?
Feel free to open an issue with your question
We would be very happy if you wanted to contribute improving and expanding this standard
You can contribute in any of the next ways:
- Using and expanding it :)
- Opening an issue with your proposals or improvements
- Forking the repository and opening a PR with your proposals or improvements
- Implementing the standard in a language (looking for a Ruby, Python, Perl or C/C++ implementation)
Copyright (c) 2013 Adesis Netlife S.L
Specification documentation under the GNU Free Documentation License.
Permission is granted to copy, distribute and/or modify this document
under the terms of the GNU Free Documentation License, Version 1.3
or any later version published by the Free Software Foundation;
with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
A copy of the license is included in the section entitled "GNU
Free Documentation License".