Skip to main content

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.

PlaceholderWhere it appearsWhat to put there
hanami application portcustomer.ymlserver.portExternal port on which the Hanami container listens (typically 80 or 8080).
catalogue application hostcustomer.ymlhanami.sync.catalogue.baseUrlDNS name or IP of the paired application instance (without http://).
catalogue application portSame line as abovePort of the catalogue’s HTTP endpoint (usually 80).
catalogue application userSame line as aboveUsername that Hanami will use for the catalogue’s Basic-Auth endpoint.
catalogue application passwordSame line as abovePassword for that user (prefix with {noop} only if it is plain text).
elastic hostnamecustomer-standalone.ymlenv.hanami.elasticsearch.url and in indexTemplateFully-qualified host (and optional port) of your Elasticsearch/Opensearch cluster, e.g. es-prod.internal:9200.
elastic usernamecustomer-standalone.ymlenv.hanami.elasticsearch.* and in indexTemplate prefixService account that owns the indices (e.g. hanami or a dedicated app user).
elastic passwordSame block as abovePassword or API key for the Elasticsearch user.
elastic max request sizecustomer-standalone.ymlmaxRequestSizeBytesMaximum document size (in bytes) accepted by the cluster; consult your ES admin.
triplestore hostnamecustomer-standalone.ymlrdfStoreHostname (and optional port) of GraphDB/Virtuoso/etc. without protocol.
triplestore portSame fieldPort on which the SPARQL endpoint is exposed (e.g. 7200).
triplestore sparqlendpoint pathSame fieldPath that follows the host/port, e.g. repositories/ep-data or simply sparql.
triplestore userrdfStoreUserLogin used by Hanami to write to the external triplestore.
triplestore passwordrdfStorePasswordPassword for that user.
resourceserver issuer-urisecurity.ymlspring.security.oauth2.resourceserver.jwt.issuer-uriThe issuer (authority) that minted the access tokens—e.g. https://login.microsoftonline.com/{tenantID}/v2.0.
client issuer-urisecurity.ymlspring.security.oauth2.client.provider.AzureADProvider.issuer-uriSame as above (many IdPs require it twice—once for RS, once for client).
client-idsecurity.ymlclient.registration.hanamidevadfsrest.client-idOAuth 2.0 client ID registered for Hanami in your IdP (ADFS/AzureAD).
client-secretSame blockClient 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