Example configuration Hanami (up to v1.5.x): Auth-enabled Docker installation
This guide shows a minimal but complete set of configuration files to run
Hanami in Docker with OAuth2 / JWT (ADFS) authentication. Copy the three
YAML files below into /opt/hanami-ext/config/
inside your container (or bind
mount that directory).
Below is a quick reference for every angle-bracket placeholder in the OAuth-enabled Docker example and what value you should supply in a real deployment.
Placeholder | Where it appears | What to put there |
---|---|---|
hanami application port | customer.yml → server.port | External port on which the Hanami container listens (typically 80 or 8080 ). |
catalogue application host | customer.yml → hanami.sync.catalogue.baseUrl | DNS name or IP of the paired application instance (without http:// ). |
catalogue application port | Same line as above | Port of the catalogue’s HTTP endpoint (usually 80 ). |
catalogue application user | Same line as above | Username that Hanami will use for the catalogue’s Basic-Auth endpoint. |
catalogue application password | Same line as above | Password for that user (prefix with {noop} only if it is plain text). |
elastic hostname | customer-standalone.yml → env.hanami.elasticsearch.url and in indexTemplate | Fully-qualified host (and optional port) of your Elasticsearch/Opensearch cluster, e.g. es-prod.internal:9200 . |
elastic username | customer-standalone.yml → env.hanami.elasticsearch.* and in indexTemplate prefix | Service account that owns the indices (e.g. hanami or a dedicated app user). |
elastic password | Same block as above | Password or API key for the Elasticsearch user. |
elastic max request size | customer-standalone.yml → maxRequestSizeBytes | Maximum document size (in bytes) accepted by the cluster; consult your ES admin. |
triplestore hostname | customer-standalone.yml → rdfStore | Hostname (and optional port) of GraphDB/Virtuoso/etc. without protocol. |
triplestore port | Same field | Port on which the SPARQL endpoint is exposed (e.g. 7200 ). |
triplestore sparqlendpoint path | Same field | Path that follows the host/port, e.g. repositories/ep-data or simply sparql . |
triplestore user | rdfStoreUser | Login used by Hanami to write to the external triplestore. |
triplestore password | rdfStorePassword | Password for that user. |
resourceserver issuer-uri | security.yml → spring.security.oauth2.resourceserver.jwt.issuer-uri | The issuer (authority) that minted the access tokens—e.g. https://login.microsoftonline.com/{tenantID}/v2.0 . |
client issuer-uri | security.yml → spring.security.oauth2.client.provider.AzureADProvider.issuer-uri | Same as above (many IdPs require it twice—once for RS, once for client). |
client-id | security.yml → client.registration.hanamidevadfsrest.client-id | OAuth 2.0 client ID registered for Hanami in your IdP (ADFS/AzureAD). |
client-secret | Same block | Client secret generated in the IdP for that application. |
Replace the entire placeholder—including angle brackets—with the real value.
1. customer.yml
Located at /opt/hanami-ext/config/customer.yml
– runtime defaults and
customer-specific settings.
server:
port: <hanami application port>
forward-headers-strategy: NATIVE
tomcat:
accesslog:
enabled: true
directory: /opt/hanami/logs
local:
assets:
folder: /opt/hanami/ext/override
hanami:
backup:
enabled: true
sync:
eventTransmission:
enabled: true
catalogue:
baseUrl: "http://<catalogue application host>:<catalogue application port>"
username: "<catalogue application user>"
password: "{noop}<catalogue application password>"
authorization:
provider: wac # operations / wac
elasticsearch:
url: ${env.hanami.elasticsearch.url}
user: ${env.hanami.elasticsearch.username}
username: ${env.hanami.elasticsearch.username}
password: ${env.hanami.elasticsearch.password}
trust: ${env.hanami.elasticsearch.trust}
lang:
app:
default-lang: en
available-langs:
- en
- fr
locale-mapping:
en: fr-BE
fr: fr-BE
data:
available-langs:
- en
- fr
prefixes:
adms: http://www.w3.org/ns/adms#
cz-internal: http://cogni.internal.system/model#
dc: http://purl.org/dc/elements/1.1/
dcat: http://www.w3.org/ns/dcat#
dct: http://purl.org/dc/terms/
eli: http://data.europa.eu/eli/ontology#
euvoc: http://publications.europa.eu/ontology/euvoc#
foaf: http://xmlns.com/foaf/0.1/
hanami: https://hanami.app/ontology#
jolux: http://data.legilux.public.lu/resource/ontology/jolux#
owl: http://www.w3.org/2002/07/owl#
prov: http://www.w3.org/ns/prov#
rdf: http://www.w3.org/1999/02/22-rdf-syntax-ns#
rdfs: http://www.w3.org/2000/01/rdf-schema#
schema: http://schema.org/
sh: http://www.w3.org/ns/shacl#
skos: http://www.w3.org/2004/02/skos/core#
sw-vocab-status: http://www.w3.org/2003/06/sw-vocab-status/ns#
uneskos: http://purl.org/umu/uneskos#
vann: http://purl.org/vocab/vann/
vcard: http://www.w3.org/2006/vcard/ns#
xsd: http://www.w3.org/2001/XMLSchema#
cognizone:
vinz:
routes:
- name: elasticsearch
path: /proxy/elasticsearch/**
url: ${hanami.elasticsearch.url}
2. customer-standalone.yml
Overlay file for container-specific values: environment IDs, external services,
index templates, and feature toggles. Path:
/opt/hanami-ext/config/customer-standalone.yml
.
info:
app:
environmentName: docker
env:
hanami:
id: "hanami-skos"
elasticsearch:
url: "https://<elastic hostname>"
username: "<elastic username>"
password: "<elastic password>"
trust: true
indexTemplate:
history: <elastic username>.history-{id}
data: <elastic username>.hanami-data-{id}
validation: <elastic username>.hanami-validation-{id}
maxRequestSizeBytes: <elastic max request size>
hanami:
security:
trusted: true
features:
actions:
enabled: false
index:
full-node-indexing:
enabled: true
partition-size: 1
pool:
size: 1
retry:
max-tries: 1
startup:
workspaces:
- uri: https://data.hanami.app/config/workspace/1
clear: true # TODO: most likely false
collections:
permissions:
delete-enabled: true
create-enabled: true
customer:
template-arguments:
rdfStore: "http://<triplestore hostname>:<triplestore port>/<triplestore sparqlendpoint path>"
rdfStoreUser: "<triplestore user>"
rdfStorePassword: "<triplestore password>"
3. customer-workflow.yml
Defines user-triggered workflow actions (publish, deprecate, etc.). Save as
/opt/hanami-ext/config/customer-workflow.yml
.
hanami:
features:
actions:
enabled: false
wfEnabled: true
workflow:
actions:
# Dataset actions
- id: dataset-publish
icon: publish
validationQuery: |
prefix adms: <http://www.w3.org/ns/adms#>
prefix dcat: <http://www.w3.org/ns/dcat#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix status: <https://data.in.ep.europa.eu/def/record-status/>
ASK WHERE {
GRAPH <#{[graphUri]}> {
?dataset a dcat:Dataset .
?record a dcat:CatalogRecord ;
foaf:primaryTopic ?dataset ;
adms:status ?status .
FILTER(?status IN (status:under-review, status:deprecated)) .
}
}
jobs:
- dataset-publish-action
excludeJobs: dataset-reset-onsave
i18n:
actionLabel: customer.workflow_actions.dataset.publish.action_label
confirmationTitle: customer.workflow_actions.dataset.publish.confirmation_title
confirmationBody: customer.workflow_actions.dataset.publish.confirmation_body
confirmationOk: customer.workflow_actions.dataset.publish.confirmation_ok
successLabel: customer.workflow_actions.dataset.publish.success_label
- id: dataset-deprecate
icon: archive
validationQuery: |
prefix adms: <http://www.w3.org/ns/adms#>
prefix dcat: <http://www.w3.org/ns/dcat#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix status: <https://data.in.ep.europa.eu/def/record-status/>
ASK WHERE {
GRAPH <#{[graphUri]}> {
?dataset a dcat:Dataset .
?record a dcat:CatalogRecord ;
foaf:primaryTopic ?dataset ;
adms:status status:current .
}
}
jobs:
- dataset-deprecate-action
excludeJobs: dataset-reset-onsave
i18n:
actionLabel: customer.workflow_actions.dataset.deprecate.action_label
confirmationTitle: customer.workflow_actions.dataset.deprecate.confirmation_title
confirmationBody: customer.workflow_actions.dataset.deprecate.confirmation_body
confirmationOk: customer.workflow_actions.dataset.deprecate.confirmation_ok
successLabel: customer.workflow_actions.dataset.deprecate.success_label
- id: dataset-to-review
icon: overview
validationQuery: |
prefix adms: <http://www.w3.org/ns/adms#>
prefix dcat: <http://www.w3.org/ns/dcat#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix status: <https://data.in.ep.europa.eu/def/record-status/>
ASK WHERE {
GRAPH <#{[graphUri]}> {
?dataset a dcat:Dataset .
?record a dcat:CatalogRecord ;
foaf:primaryTopic ?dataset ;
adms:status status:draft .
}
}
jobs:
- dataset-to-review-action
excludeJobs: dataset-reset-onsave
i18n:
actionLabel: customer.workflow_actions.dataset.to_review.action_label
confirmationTitle: customer.workflow_actions.dataset.to_review.confirmation_title
confirmationBody: customer.workflow_actions.dataset.to_review.confirmation_body
confirmationOk: customer.workflow_actions.dataset.to_review.confirmation_ok
successLabel: customer.workflow_actions.dataset.to_review.success_label
- id: dataset-back-to-draft
icon: plagiarism
validationQuery: |
prefix adms: <http://www.w3.org/ns/adms#>
prefix dcat: <http://www.w3.org/ns/dcat#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix status: <https://data.in.ep.europa.eu/def/record-status/>
ASK WHERE {
GRAPH <#{[graphUri]}> {
?dataset a dcat:Dataset .
?record a dcat:CatalogRecord ;
foaf:primaryTopic ?dataset ;
adms:status ?status .
FILTER(?status IN (status:under-review, status:current, status:deprecated)) .
}
}
jobs:
- dataset-back-to-draft-action
excludeJobs: dataset-reset-onsave
i18n:
actionLabel: customer.workflow_actions.dataset.back_to_draft.action_label
confirmationTitle: customer.workflow_actions.dataset.back_to_draft.confirmation_title
confirmationBody: customer.workflow_actions.dataset.back_to_draft.confirmation_body
confirmationOk: customer.workflow_actions.dataset.back_to_draft.confirmation_ok
successLabel: customer.workflow_actions.dataset.back_to_draft.success_label
# Additional Data Service actions truncated for brevity…
Note – For a real deployment include the remaining data-service actions exactly as supplied in your template.
4. security.yml
Finally, wire OAuth/JWT (adfs
) via Spring Security. File path:
/opt/hanami-ext/config/security.yml
.
hanami:
security:
iam:
enable: true
user-onboarding:
enable: true
user-auto-create:
user-collection-graph: https://hanami.app/shacl/user/collection
user-model-template: | # supports {uuid} and {username} placeholders
@prefix hanami: <https://hanami.app/ontology#> .
@prefix vcard: <http://www.w3.org/2006/vcard/ns#> .
@prefix acl: <http://www.w3.org/ns/auth/acl#> .
<https://hanami.app/auth/user/{username}>
a vcard:Individual ;
vcard:fn "{username}" ;
vcard:hasUID "{uuid}" ;
hanami:username "{username}" ;
hanami:isAdmin false.
user-group-collection: https://hanami.app/shacl/user-group/collection
user-group-graph-uri: https://hanami.app/auth/usergroup/basic-users/graph # supports {uuid} and {username} placeholders
user-graph-update-query-template: |
PREFIX vcard: <http://www.w3.org/2006/vcard/ns#>
PREFIX hanami: <https://hanami.app/ontology#>
INSERT DATA {
<https://hanami.app/auth/usergroup/basic-users> vcard:hasMember <https://hanami.app/auth/user/{username}> .
}
spring:
security:
oauth2:
resourceserver:
jwt:
issuer-uri: <resourceserver issuer-uri>
client:
registration:
hanamidevadfsrest:
provider: AzureADProvider
client-id: <client-id>
client-secret: <client-secret>
scope: openid,profile,email
provider:
AzureADProvider:
issuer-uri: <client issuer-uri>
user-name-attribute: uid
cognizone:
security:
auth-method: basic