I18N
local i18n = require("nauthilus_i18n")
The nauthilus_i18n module is a companion API for deployment-owned localization work. Final authentication responses should normally use auth.policy.policies[*].then.response_message.from: i18n plus optional response_language, because that keeps policy reports and HTTP, gRPC, and IdP rendering on one shared path.
Use this Lua module when a startup script needs to register deployment catalog overlays, or when request-time Lua needs localized text for Lua-owned logs, notices, or fallback strings.
nauthilus_i18n.get_localized
Resolves one stable localization key through the active effective catalog.
Syntax
local localized = i18n.get_localized({
i18n_key = "auth.policy.company.account_locked",
fallback = "Login failed because the account is locked.",
language = "de",
})
Parameters
The function accepts exactly one Lua table.
| Field | Required | Meaning |
|---|---|---|
i18n_key | yes | Stable catalog key. |
fallback | yes | Text returned when the key or selected language cannot be localized. |
language | no | BCP 47 language tag. When omitted, Nauthilus uses the request's current language preference. |
Returns
The function returns exactly one Lua table.
| Field | Meaning |
|---|---|
message | Rendered localized message, or fallback text. |
language | Selected language tag, when one was selected. |
localized | true when a catalog entry was used. |
i18n_key | Requested key. |
fallback_used | true when fallback text was returned. |
Example
local i18n = require("nauthilus_i18n")
local localized = i18n.get_localized({
i18n_key = "auth.policy.company.account_locked",
fallback = "Login failed because the account is locked.",
language = "en",
})
nauthilus_builtin.custom_log_add("localized_policy_message", localized.message)
nauthilus_builtin.custom_log_add("localized_policy_language", localized.language)
get_localized is read-only. It uses the same resolver semantics as policy response rendering: invalid or unsupported languages fall through to the next preference, missing translations return fallback, and maximum response-message length rules still apply.
nauthilus_i18n.register_catalog
Registers deployment-owned catalog entries during startup or init Lua execution.
Syntax
i18n.register_catalog({
language = "en",
namespace = "company",
entries = {
["auth.policy.company.account_locked"] = "Login failed because the account is locked.",
["auth.policy.company.account_unpaid"] = "Login failed because open payments exist and the account is locked.",
},
})
Parameters
The function accepts exactly one Lua table.
| Field | Required | Meaning |
|---|---|---|
language | yes | BCP 47 language tag for all entries in the table. |
namespace | no | Deployment namespace used in diagnostics and override logs. |
entries | yes | Table mapping stable i18n keys to localized strings. |
Runtime Rules
register_catalogis available only during startup or init Lua execution.- Request-time Lua cannot mutate the active effective catalog.
- Deployment overlays are merged after the system catalog in deterministic order.
- Deployment overlays may add new keys and override system keys.
- Overrides are logged with language, key, namespace, and previous namespace.
- After startup succeeds, the effective catalog is frozen for request-time use.
- On reload, Nauthilus builds and validates the next effective catalog first. The new catalog is activated atomically only after the reload succeeds. A failed reload keeps the previous catalog active.
Startup Example
Configure the init script as a Lua backend init script:
auth:
backends:
lua:
backend:
default:
init_script_paths:
- /etc/nauthilus/policy/i18n.lua
local i18n = require("nauthilus_i18n")
i18n.register_catalog({
language = "en",
namespace = "company",
entries = {
["auth.policy.company.account_locked"] = "Login failed because the account is locked.",
["auth.policy.company.account_unpaid"] = "Login failed because open payments exist and the account is locked.",
},
})
The corresponding policy selects the key and fallback text:
auth:
policy:
policies:
- name: deny_company_locked_account
stage: auth_decision
operations: [authenticate]
if:
attribute: lua.company.account_status
eq: locked
then:
decision: deny
response_marker: auth.response.fail
response_message:
from: i18n
i18n_key: auth.policy.company.account_locked
fallback: "Login failed because the account is locked."
Do not add deployment example keys such as auth.policy.company.* to Nauthilus system resource files. Keep them in deployment-owned startup catalogs or external deployment material.
Testing and Mocks
Tests should use fake catalogs, fake resolvers, or fake startup catalog collectors. They do not need real Redis, LDAP, backend authentication, or production resource bundles.
Useful focused cases:
get_localizedaccepts exactly one table.- Missing
i18n_keyorfallbackfails. - The return table contains
message,language,localized,i18n_key, andfallback_used. - Missing keys return fallback text.
- Invalid languages fall back through the resolver preference chain.
- Deployment overlays override system keys.
- Request-time Lua cannot call
register_catalog. - Failed reload keeps the previous effective catalog active.