Authly configuration documents
Authly's attribute-based identity and access control model is configured through sequentially applied, declarative TOML documents. Any number of these documents can be included from the configuration setting AUTHLY_DOCUMENT_PATH
, and any definition can depend on a previous defintion. To give them some sort of order, they are usually prefixed with a number to ensure they are processed correctly in lexicographical order, e.g.:
0_core.toml
1_services.toml
2_users.toml
Although the documents are intended to be human-readable and -writable, the definitions therein will eventually be accessible through a more user-friendly admin UI.
A full example, step by step
[authly-document]
id = "18d70399-0e89-46b8-81ce-a6a16e5db7cc"
The document requires an authly-document
clause at the top, with a UUID id
value.
[[service-entity]]
eid = "s.3c2f40b3f47a4d9b9129b1e7c15fbc04"
label = "arx"
attributes = ["authly:role:authenticate", "authly:role:get_access_token"]
kubernetes-account = { name = "arx" }
This defines the "arx"
gateway as a kubernetes service-entity. The gateway is responsible for opening up the public aspects of Authly to the world outside the cluster.
Service entity ids are prefixed by s.
.
The built-in attribute triplets "authly:role:authenticate"
and "authly:role:get_access_token"
allows anyone to authenticate and get access tokens through the gateway. An attribute triplet is a colon-separated namespace:label:attribute
string.
The kubernetes-account
is used by Authly to provision the service with an mTLS client certificate, used for (service) authentication.
It only specifies an account name, and not a namespace
. Not specifying the namespace means the same namespace that Authly itself runs within.
[[service-entity]]
eid = "s.ec29ba1d23cb43f89b7c73db6f177a1d"
label = "ultradb"
hosts = ["ultradb"]
kubernetes-account = { name = "ultradb" }
This defines the "ultradb"
service-entity, hosted as a kubernetes service behind the "arx"
. Service-enitity labels are exposed as namespaces in the Authly model.
[[service-entity]]
eid = "s.a1c6134658dd4120823fdc42bb2f42ad"
label = "ultradb_gui"
hosts = ["ultradb-gui"]
This defines the "ultradb_gui"
(client) service-entity, hosted by "ultradb"
.
[[entity-property]]
namespace = "ultradb_gui"
label = "role"
attributes = ["user", "admin"]
This defines the entity-property "role"
for the "ultradb_gui"
client.
Its attributes are "user"
and "admin"
.
In other words, we make the client responsible for the concept of a (persona) entity role, since users access the service through the client.
[[resource-property]]
namespace = "ultradb"
label = "action"
attributes = ["read", "write"]
This defines the resource-property "action"
for the "ultradb"
service.
Its attributes are "read"
and "write"
.
In other words, we make the service is responsible for its own resources, since users access resources (data) via the service's API.
[[policy]]
label = "allow for GUI user"
allow = "Subject.ultradb_gui:role contains ultradb_gui:role:user"
This defines a policy called "allow for GUI user"
.
The policy must either define an allow
or a deny
expression. This policy will resolve to allow
if the expression resolves to true
.
Subject
is the one being access-controlled. ultradb_gui:role
is a namespaced entity property, and ultradb_gui:role:user
is an attribute assigned to an entity (see below).
Referencing the entity-properties above, this should read as "allow if the Subject has the ultradb_gui role user".
[[policy]]
label = "allow for GUI admin"
allow = "Subject.ultradb_gui:role contains ultradb_gui:role:admin"
This defines a policy called "allow for GUI admin"
, similar to the one above.
Referencing the entity-properties above, this should read as "allow if the Subject has the ultradb_gui role admin".
[[policy-binding]]
attributes = ["ultradb:action:read"]
policies = ["allow for GUI user", "allow for GUI admin"]
This defines a policy-binding, from a list of policies to a list of colon-separated attribute triplets (namespace:label:attribute
).
Referencing the resource-properties and policies, this should read as "GUI users and GUI admins are allowed the ultradb action read".
[[policy-binding]]
attributes = ["ultradb:action:write"]
policies = ["allow for GUI admin"]
This defines a policy-binding, from a list of policies to a list of colon-separated attribute triplets (namespace:label:attribute
).
Referencing the resource-properties and policies, this should read as "GUI admins are allowed the ultradb action write".
[[entity]]
eid = "p.96bf83f88cbf455fa356553f7fca1b9e"
label = "Mr. User"
This defines a (persona) entity, "Mr. User"
. For now, they don't have any access credentials.
Persona entity ids are prefixed by p.
.
[[entity]]
eid = "p.81dc1da0fa644142bad35043a9c3b025"
label = "Ms. Admin"
This defines a (persona) entity, "Ms. Admin"
. For now, they don't have any access credentials.
[[entity-attribute-assignment]]
entity = "Mr. User"
attributes = ["ultradb_gui:role:user"]
This defines an entity-attribute-assignment.
Referencing the entities and entity-properties above, this should read as "Mr. User has the ultradb_gui role user".
[[entity-attribute-assignment]]
entity = "Ms. Admin"
attributes = ["ultradb_gui:role:admin"]
This defines an entity-attribute-assignment.
Referencing the entities and entity-properties above, this should read as "Ms. Admin has the ultradb_gui role admin".
To summarize, this document defines three service-entities, and allows anyone to authenticate and resolve an authentication token through the service "arx" (if they had credentials). We define some entity-properties and resource-properties to describe our access control model, and policies are bound to the resource-properties through policy-bindings. Finally, a pair of entities are defined, and are assigned entity attributes through entity-attribute-assignments.
Clauses
[authly-document]
Required. Metadata about the document. Every document must have one of these clauses the top.
Properties:
id
: Required. A UUID value.
Example:
[authly-document]
id = "3ef3430a-6499-497c-b8eb-00516a22f326"
[[entity]]
An entity definition, e.g. a persona or a group.
Properties:
eid
: Required. The entity id. Persona entity ids are prefixed byp.
, while group entity ids are prefixed byg.
. The value is a hex-encoded 128-bit value.label
: A label for the entity visible in the document namespace.attributes
: Attributes bound to the entity. See entity-attribute-assignment.username
: A list of usernames.email
: A list of email addresses.password-hash
: A list of password hashes.
Example:
[[entity]]
eid = "p.0fbcd73e1a884424a1615c3c3fdeebea"
label = "me"
username = "me"
password-hash = [
"$argon2id$v=19$m=19456,t=2,p=1$/lj8Yj6ZTJLiqgpYb4Nn0g$z79FFMXstrkY8KmpC0vQWIDcne0lylBbctUAluIVqLk"
]
[[service-entity]]
A service entity definition.
Services are authenticated through client certificates rather than traditional credentials.
Properties:
eid
: Required. The entity id. Service entity ids are prefixed bys.
.label
: A label for the entity visible in the document namespace.attributes
: Attributes bound to the entity. See entity-attribute-assignment.metadata
: Metadata about this entity. The metadata is not used by authly itself, but can be used by services which have read access to the entity.hosts
: List of service hostnames.kubernetes-account
: An optional Kubernetes account definition.
Example:
[[service-entity]]
eid = "s.3c2f40b3f47a4d9b9129b1e7c15fbc0c"
label = "service"
metadata = { meta = "meta" }
kubernetes-account = { name = "service", namespace = "myspace" }
[[email]]
An email address assignment.
Can also be given as part of an email
property list of an [[entity]]
clause.
Properties:
entity
: The label of the entity that is assigned this address.value
: The address itself.
Example:
[[email]]
entity = "me"
value = "me@mail.com"
[[password-hash]]
A password hash assignment.
Can also be given as part of a password-hash
property list of an [[entity]]
clause.
Properties:
entity
: The label of the entity that is assigned this password.hash
: The password hash itself.
Example:
[[password-hash]]
entity = "you"
hash = "$argon2id$v=19$m=19456,t=2,p=1$/lj8Yj6ZTJLiqgpYb4Nn0g$z79FFMXstrkY8KmpC0vQWIDcne0lylBbctUAluIVqLk"
[[members]]
A members assignment, giving a (group) entity other entities as members.
In the Authly model, any kind of entity may have members.
Properties:
entity
: The label of the entity that members are assigned to.members
: List of entity labels of the members.
Example:
[[members]]
entity = "us"
members = ["me", "you"]
[[domain]]
A domain declaration.
Properties:
label
: Required. A label for an entity visible in the document namespace.metadata
: Metadata about this domain. The metadata is not used by Authly itself, but can be read and used by services.
Example:
[[domain]]
label = "cms"
metadata = { meta = "meta" }
[[service-domain]]
An association of a service and a domain the service can use.
Properties:
service
: Required. A label identifying the implied service-entity.domain
: Required. A label identifying the domain that will be exposed to the service.
Example:
[[service-domain]]
service = "service"
domain = "cms"
[[entity-property]]
A definition of an entity property.
Properties:
namespace
: Required. The label of the namespace this property is defined inside.label
: Required. The property label.attributes
: The list of attributes of the property.
Example:
[[entity-property]]
namespace = "service"
label = "role"
attributes = ["user", "admin"]
[[entity-attribute-assignment]]
An entity attribute binding, which assigns attributes to entities.
Can also be given as part of a attributes
property list on an [[entity]]
or [[service-entity]]
.
Properties:
entity
: Required. An Entity ID or label identifying the entity to assign to.attributes
: Required. The attributes assigned to the entity.
Example:
[[entity-attribute-assignment]]
entity = "me"
attributes = ["service:role:user"]
[[resource-property]]
A definition of a resource property.
Properties:
namespace
: Required. The label of the namespace this property is defined inside.label
: Required. The property label.attributes
: The list of attributes of the property.
Example:
[[resource-property]]
namespace = "service"
label = "action"
attributes = ["read", "create", "delete"]
[[policy]]
A policy definition.
A policy must contain either an allow
or deny
expression.
Access may be granted if any allow-policy evaluates to true
, unless there are applicable deny-policies.
deny-policies are stronger than allow-policies: Access will be denied if any applicable deny-policy evaluates to true
.
Properties:
service
: Required. A label identifying the implied service-entity.domain
: Required. A label identifying the domain that will be exposed to the service.
Example:
[[policy]]
label = "allow for service"
allow = "Subject.authly:entity == service"
[[policy-binding]]
A policy binding.
A policy binding makes policies applicable in the context of the binding's attribute matcher.
Properties:
attributes
: Required. A set of attribute triples that must be matched for the selected policies to apply.policies
: Required. A set of applied policies, by label.
Example:
[[policy-binding]]
attributes = ["service:action:read"]
policies = ["allow for service"]