@o3co/create-auth-provider 0.17.0-rc.4 → 0.18.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -198
- package/main.js +4 -0
- package/package.json +8 -30
- package/README.ja.md +0 -200
- package/dist/cli.d.mts +0 -3
- package/dist/cli.d.mts.map +0 -1
- package/dist/cli.mjs +0 -18
- package/dist/index.d.mts +0 -48
- package/dist/index.d.mts.map +0 -1
- package/dist/index.mjs +0 -325
- package/dist/internal/template-filter.d.mts +0 -14
- package/dist/internal/template-filter.d.mts.map +0 -1
- package/dist/internal/template-filter.mjs +0 -42
- package/templates/standalone/.dockerignore +0 -23
- package/templates/standalone/.env.example +0 -152
- package/templates/standalone/Dockerfile +0 -125
- package/templates/standalone/Makefile +0 -12
- package/templates/standalone/README.ja.md +0 -913
- package/templates/standalone/README.md +0 -1537
- package/templates/standalone/config/application.conf +0 -351
- package/templates/standalone/config/clients.yaml +0 -4
- package/templates/standalone/config/clients.yaml.example +0 -118
- package/templates/standalone/config/development.conf +0 -17
- package/templates/standalone/config/mailpit.conf +0 -13
- package/templates/standalone/config/production.conf +0 -15
- package/templates/standalone/config/reference.conf +0 -424
- package/templates/standalone/docker-compose.mailpit.yml +0 -39
- package/templates/standalone/docker-compose.production.yml +0 -229
- package/templates/standalone/docker-compose.test.yml +0 -16
- package/templates/standalone/docker-compose.yml +0 -67
- package/templates/standalone/gitignore +0 -23
- package/templates/standalone/package.json +0 -55
- package/templates/standalone/src/__tests__/adapters.test.mts +0 -425
- package/templates/standalone/src/__tests__/admission-lifecycle.test.mts +0 -87
- package/templates/standalone/src/__tests__/all-modules-composition.fixture.mts +0 -1192
- package/templates/standalone/src/__tests__/all-modules-composition.multi.test.mts +0 -285
- package/templates/standalone/src/__tests__/all-modules-composition.test.mts +0 -1154
- package/templates/standalone/src/__tests__/audit-sink.test.mts +0 -346
- package/templates/standalone/src/__tests__/config-notices.test.mts +0 -157
- package/templates/standalone/src/__tests__/configPath.test.mts +0 -69
- package/templates/standalone/src/__tests__/configured-mfa-mode.fixture.mts +0 -48
- package/templates/standalone/src/__tests__/core-federations.test.mts +0 -252
- package/templates/standalone/src/__tests__/core-sections.test.mts +0 -192
- package/templates/standalone/src/__tests__/device-code-store-client-module.test.mts +0 -95
- package/templates/standalone/src/__tests__/documented-env-overrides.test.mts +0 -1290
- package/templates/standalone/src/__tests__/federation-grants-composition.test.mts +0 -784
- package/templates/standalone/src/__tests__/federation-grants-survive-logout.test.mts +0 -461
- package/templates/standalone/src/__tests__/federation-token-refresh-outage.test.mts +0 -141
- package/templates/standalone/src/__tests__/federation-types.test.mts +0 -239
- package/templates/standalone/src/__tests__/google-session.fixture.mts +0 -308
- package/templates/standalone/src/__tests__/host-routes.test.mts +0 -134
- package/templates/standalone/src/__tests__/library-reference-resolution.smoke.test.mts +0 -29
- package/templates/standalone/src/__tests__/library-references.fixture.mts +0 -188
- package/templates/standalone/src/__tests__/lifecycle-pending-close.test.mts +0 -216
- package/templates/standalone/src/__tests__/listen.test.mts +0 -121
- package/templates/standalone/src/__tests__/logger-projection.test.mts +0 -77
- package/templates/standalone/src/__tests__/logout-session-cookie.test.mts +0 -113
- package/templates/standalone/src/__tests__/mail-sender.test.mts +0 -134
- package/templates/standalone/src/__tests__/mailpit-compose.test.mts +0 -393
- package/templates/standalone/src/__tests__/metrics.test.mts +0 -253
- package/templates/standalone/src/__tests__/mfa-routes-budget.test.mts +0 -122
- package/templates/standalone/src/__tests__/mfa-switch.redis.test.mts +0 -127
- package/templates/standalone/src/__tests__/mfa-switch.test.mts +0 -883
- package/templates/standalone/src/__tests__/own-modules.test.mts +0 -1512
- package/templates/standalone/src/__tests__/post-logout-redirect.test.mts +0 -183
- package/templates/standalone/src/__tests__/redis-assume-noeviction.test.mts +0 -214
- package/templates/standalone/src/__tests__/redis-connection-error-log.test.mts +0 -135
- package/templates/standalone/src/__tests__/redis-rate-limiter-config-survives.test.mts +0 -214
- package/templates/standalone/src/__tests__/refresh-token-family-client-module.test.mts +0 -249
- package/templates/standalone/src/__tests__/replica-safety.test.mts +0 -654
- package/templates/standalone/src/__tests__/repositories-logger.test.mts +0 -119
- package/templates/standalone/src/__tests__/router-error-answers.test.mts +0 -146
- package/templates/standalone/src/__tests__/scaffold-assets.test.mts +0 -610
- package/templates/standalone/src/__tests__/sections.test.mts +0 -504
- package/templates/standalone/src/__tests__/session-lifecycle.test.mts +0 -215
- package/templates/standalone/src/__tests__/session-logout-invalidates-token.test.mts +0 -296
- package/templates/standalone/src/__tests__/session-logout-lifecycle.test.mts +0 -130
- package/templates/standalone/src/__tests__/session-requirements.test.mts +0 -382
- package/templates/standalone/src/__tests__/shipped-config-notices.test.mts +0 -274
- package/templates/standalone/src/__tests__/shutdown.test.mts +0 -622
- package/templates/standalone/src/__tests__/smoke.test.mts +0 -634
- package/templates/standalone/src/__tests__/startup-log-lines.test.mts +0 -148
- package/templates/standalone/src/__tests__/store-credential.test.mts +0 -312
- package/templates/standalone/src/__tests__/supertest-loopback.test.mts +0 -296
- package/templates/standalone/src/__tests__/three-tier-resolution.test.mts +0 -265
- package/templates/standalone/src/__tests__/two-phase-config.test.mts +0 -605
- package/templates/standalone/src/__tests__/upstream-amr.acceptance.test.mts +0 -382
- package/templates/standalone/src/adapters.mts +0 -162
- package/templates/standalone/src/app.mts +0 -136
- package/templates/standalone/src/bootRefusal.mts +0 -117
- package/templates/standalone/src/buildModules.mts +0 -358
- package/templates/standalone/src/configPath.mts +0 -487
- package/templates/standalone/src/listen.mts +0 -60
- package/templates/standalone/src/logger.mts +0 -80
- package/templates/standalone/src/metrics.mts +0 -167
- package/templates/standalone/src/mfaSwitch.mts +0 -284
- package/templates/standalone/src/modules.mts +0 -705
- package/templates/standalone/src/rootRenames.mts +0 -95
- package/templates/standalone/src/routes.mts +0 -89
- package/templates/standalone/src/sections.mts +0 -377
- package/templates/standalone/src/shutdown.mts +0 -213
- package/templates/standalone/tests/Makefile +0 -5
- package/templates/standalone/tests/index.test.js +0 -283
- package/templates/standalone/tests/package-lock.json +0 -1617
- package/templates/standalone/tests/package.json +0 -16
- package/templates/standalone/tests/vitest.config.mjs +0 -26
- package/templates/standalone/tsconfig.json +0 -31
- package/templates/standalone/vitest.config.mts +0 -31
- package/templates/standalone/vitest.supertest-loopback.mts +0 -278
- package/templates/versions.json +0 -20
|
@@ -1,424 +0,0 @@
|
|
|
1
|
-
# Defaults of the standalone template's own modules (src/modules.mts), each in
|
|
2
|
-
# the section named after its module, and of its own `adapters` and
|
|
3
|
-
# `mfaMode`, each key with its variable, named after its path, and the MFA
|
|
4
|
-
# routes' budget in each rate limiter's section (below `mfaMode`). Layered
|
|
5
|
-
# beneath application.conf and {env}.conf: set a deployment's own values
|
|
6
|
-
# there, not here. A value either file sets wins over
|
|
7
|
-
# the variable bound here, except for HTTP_PORT, HTTP_TRUST_PROXY,
|
|
8
|
-
# HTTP_CORS_ALLOWED_ORIGINS and REDIS_CLIENTS_URL / _PASSWORD, which
|
|
9
|
-
# application.conf binds again in its last lines, so they win over a value it
|
|
10
|
-
# sets above them.
|
|
11
|
-
|
|
12
|
-
# `logging`: trace | debug | info | warn | error | fatal | silent. `trace` and
|
|
13
|
-
# `debug` carry request-shaped detail; `silent` spares only the audit trail.
|
|
14
|
-
logging {
|
|
15
|
-
level = "info"
|
|
16
|
-
level = ${?LOGGING_LEVEL}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
# `http`: the listener, the trusted forwarding hops, the readiness deadline and
|
|
20
|
-
# the CORS list.
|
|
21
|
-
http {
|
|
22
|
-
port = 3000
|
|
23
|
-
port = ${?HTTP_PORT}
|
|
24
|
-
# Express `trust proxy`: whether X-Forwarded-For may rewrite `req.ip`
|
|
25
|
-
# (every IP-keyed rate limit) and X-Forwarded-Proto may rewrite
|
|
26
|
-
# `req.protocol`.
|
|
27
|
-
#
|
|
28
|
-
# Four shapes, all of them Express's own:
|
|
29
|
-
#
|
|
30
|
-
# false trust nothing. `req.ip` is the socket peer. The default.
|
|
31
|
-
# <address list> trust these hops, and only these. An IP literal, a CIDR
|
|
32
|
-
# range (10.0.0.0/8, fc00::/7), or a named range
|
|
33
|
-
# (loopback, linklocal, uniquelocal). This is the only
|
|
34
|
-
# shape that says WHICH hop is trusted, and it is the one
|
|
35
|
-
# to reach for. Via env var, comma-separate:
|
|
36
|
-
# HTTP_TRUST_PROXY=10.0.0.0/8,192.168.0.0/16
|
|
37
|
-
# <hop count> trust that many hops back from the socket peer, e.g. 1
|
|
38
|
-
# for exactly one reverse proxy in front of this process.
|
|
39
|
-
# true trust every hop, i.e. believe the leftmost
|
|
40
|
-
# X-Forwarded-For entry from whoever opened the connection.
|
|
41
|
-
# Correct ONLY when nothing but the proxy can route to this
|
|
42
|
-
# process; otherwise a client that reaches it directly, or
|
|
43
|
-
# through one more hop than you accounted for, forges its
|
|
44
|
-
# own `req.ip` and with it any IP-keyed rate-limit identity.
|
|
45
|
-
#
|
|
46
|
-
# Entries are validated at boot: a hostname, a mistyped keyword or a
|
|
47
|
-
# malformed prefix length fails loudly rather than becoming a rule that
|
|
48
|
-
# never matches.
|
|
49
|
-
#
|
|
50
|
-
# An allowlist is a network control, not a cryptographic one. The edge must
|
|
51
|
-
# also STRIP inbound X-Forwarded-* headers rather than appending to them,
|
|
52
|
-
# and the hop between it and this process must not be reachable by anyone
|
|
53
|
-
# able to spoof a source address.
|
|
54
|
-
#
|
|
55
|
-
# Unrelated to `mtls.trustedProxies`, which shares this vocabulary but
|
|
56
|
-
# answers a different question (may this peer forward a client certificate?)
|
|
57
|
-
# and is deliberately not derived from this key.
|
|
58
|
-
trustProxy = false
|
|
59
|
-
trustProxy = ${?HTTP_TRUST_PROXY}
|
|
60
|
-
# Per-probe deadline for /readyz and the metrics scrape's probes. Keep it
|
|
61
|
-
# below the orchestrator's own probe timeout so an unreachable dependency
|
|
62
|
-
# answers 503 rather than letting the probe hang.
|
|
63
|
-
readinessTimeoutMs = 1000
|
|
64
|
-
readinessTimeoutMs = ${?HTTP_READINESS_TIMEOUT_MS}
|
|
65
|
-
# `cors`: the browser origins allowed to read the token, userinfo,
|
|
66
|
-
# revocation and discovery/JWKS responses. Empty (the default) means CORS
|
|
67
|
-
# is off.
|
|
68
|
-
#
|
|
69
|
-
# Matching against the `Origin` request header is exact string equality,
|
|
70
|
-
# so each entry is a bare origin: scheme, host, and a port only when it is
|
|
71
|
-
# not the scheme's default; no trailing slash, no path, no wildcard. https
|
|
72
|
-
# is required except for a loopback host (localhost, 127.0.0.0/8, [::1]).
|
|
73
|
-
# Each rule is checked at boot.
|
|
74
|
-
#
|
|
75
|
-
# cors.allowedOrigins = ["https://app.example.com", "http://localhost:5173"]
|
|
76
|
-
#
|
|
77
|
-
# No credentials are ever allowed: an allowlisted origin can read these
|
|
78
|
-
# responses and cannot use the browser's session cookie. This list confers
|
|
79
|
-
# no CSRF trust; that is `session.csrf.trustedOrigins`. The variable takes a
|
|
80
|
-
# comma-separated list.
|
|
81
|
-
cors {
|
|
82
|
-
allowedOrigins = []
|
|
83
|
-
allowedOrigins = ${?HTTP_CORS_ALLOWED_ORIGINS}
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
# `key-store`: the JWT signing key.
|
|
88
|
-
key-store {
|
|
89
|
-
provider = "local"
|
|
90
|
-
provider = ${?KEY_STORE_PROVIDER}
|
|
91
|
-
local {
|
|
92
|
-
# The default is asymmetric. HS256 leaves a relying party with two bad
|
|
93
|
-
# options: verify nothing (there is no public key to publish, so
|
|
94
|
-
# /.well-known/jwks.json has nothing to serve), or hold the shared
|
|
95
|
-
# secret, which also lets it mint tokens. EdDSA (Ed25519) publishes a
|
|
96
|
-
# real JWKS and keeps signing capability here.
|
|
97
|
-
#
|
|
98
|
-
# There is no key material default and no fallback: a deployment that
|
|
99
|
-
# configures nothing fails at boot naming the keys to set, rather than
|
|
100
|
-
# quietly signing with a guessable secret.
|
|
101
|
-
#
|
|
102
|
-
# openssl genpkey -algorithm ed25519 -out jwt-private.pem
|
|
103
|
-
# openssl pkey -in jwt-private.pem -pubout -out jwt-public.pem
|
|
104
|
-
#
|
|
105
|
-
# HS256 remains selectable (KEY_STORE_LOCAL_ALGORITHM=HS256) for
|
|
106
|
-
# deployments that verify in-process and publish no JWKS. It then requires
|
|
107
|
-
# KEY_STORE_LOCAL_SECRET with at least 32 bytes (256 bits) of random material
|
|
108
|
-
# (`openssl rand -hex 32`). Hex and base64 values are measured decoded, so
|
|
109
|
-
# a 32-character hex string is only 16 bytes and is refused.
|
|
110
|
-
algorithm = "EdDSA"
|
|
111
|
-
algorithm = ${?KEY_STORE_LOCAL_ALGORITHM}
|
|
112
|
-
kid = "v0"
|
|
113
|
-
kid = ${?KEY_STORE_LOCAL_KID}
|
|
114
|
-
secret = ${?KEY_STORE_LOCAL_SECRET}
|
|
115
|
-
privateKeyPath = ${?KEY_STORE_LOCAL_PRIVATE_KEY_PATH}
|
|
116
|
-
publicKeyPath = ${?KEY_STORE_LOCAL_PUBLIC_KEY_PATH}
|
|
117
|
-
privateKey = ${?KEY_STORE_LOCAL_PRIVATE_KEY}
|
|
118
|
-
publicKey = ${?KEY_STORE_LOCAL_PUBLIC_KEY}
|
|
119
|
-
# Key rotation is shaped per algorithm family. Asymmetric algorithms
|
|
120
|
-
# (RS256, ES256, EdDSA) use `previousKeys` (kid, publicKey or
|
|
121
|
-
# publicKeyPath, expiresAt); HS256 uses `previousSecrets` (kid, secret,
|
|
122
|
-
# expiresAt). The schema is a discriminated union and the key store
|
|
123
|
-
# refuses the other family's field, so the wrong shape fails at boot
|
|
124
|
-
# rather than being dropped at verification time. Neither is declared
|
|
125
|
-
# here: the default algorithm is EdDSA, and an empty
|
|
126
|
-
# `previousSecrets = []` under it would be exactly that wrong shape. Add
|
|
127
|
-
# the one matching your algorithm in your own layer.
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
# `redis-clients`: the one ioredis socket per replica every Redis-backed store
|
|
132
|
-
# shares. More than one replica needs a shared Redis 7.2+ here; localhost
|
|
133
|
-
# inside a container is the container itself. The Redis stores that keep
|
|
134
|
-
# durable keys refuse to boot unless the server reports maxmemory-policy
|
|
135
|
-
# `noeviction`. `assumeNoEviction = true` asserts it for a server that will not
|
|
136
|
-
# report it (INFO and CONFIG refused to the connection's user); a policy the
|
|
137
|
-
# server does report always decides.
|
|
138
|
-
redis-clients {
|
|
139
|
-
url = "redis://localhost:6379"
|
|
140
|
-
url = ${?REDIS_CLIENTS_URL}
|
|
141
|
-
password = ${?REDIS_CLIENTS_PASSWORD}
|
|
142
|
-
assumeNoEviction = false
|
|
143
|
-
assumeNoEviction = ${?REDIS_CLIENTS_ASSUME_NO_EVICTION}
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
# `repositories`: the client registry, and the user repository's settings for
|
|
147
|
-
# each adapter it may be (`adapters.userRepository`). The two YAML paths are
|
|
148
|
-
# cwd-relative.
|
|
149
|
-
repositories {
|
|
150
|
-
client {
|
|
151
|
-
yaml {
|
|
152
|
-
path = "./config/clients.yaml"
|
|
153
|
-
path = ${?REPOSITORIES_CLIENT_YAML_PATH}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
user {
|
|
157
|
-
yaml {
|
|
158
|
-
path = "./config/users.yaml"
|
|
159
|
-
path = ${?REPOSITORIES_USER_YAML_PATH}
|
|
160
|
-
}
|
|
161
|
-
# The Store's HTTP endpoints. Every URL here carries what a Store must
|
|
162
|
-
# never receive in the clear -- user credentials to the first two, a
|
|
163
|
-
# verified federation token and its claims to the link and the lookup, a
|
|
164
|
-
# subject's MFA enrollment witness to the last -- so each must be an
|
|
165
|
-
# absolute https URL; http:// is accepted only for a loopback host
|
|
166
|
-
# (localhost, 127.0.0.0/8, [::1]). Each must be the endpoint that answers:
|
|
167
|
-
# no request follows a 3xx. Boot fails otherwise.
|
|
168
|
-
http {
|
|
169
|
-
authenticateUrl = ${?REPOSITORIES_USER_HTTP_AUTHENTICATE_URL}
|
|
170
|
-
authenticateByTokenUrl = ${?REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL}
|
|
171
|
-
# Optional. With it, a signed-in user can link a second federated
|
|
172
|
-
# identity (GET /session/oauth/federation/<name>?link=1) and the Store
|
|
173
|
-
# decides; without it, link=1 is refused with `link_unsupported`.
|
|
174
|
-
linkFederatedIdentityUrl = ${?REPOSITORIES_USER_HTTP_LINK_FEDERATED_IDENTITY_URL}
|
|
175
|
-
# Optional. The Store's identity lookup for federation grants. With it,
|
|
176
|
-
# declare what the lookup covers, per registration, in a HOCON layer (a
|
|
177
|
-
# list has no environment form):
|
|
178
|
-
# federatedIdentityLookupCoverage = [
|
|
179
|
-
# { provider = "entra-files", issuer = "...", clientId = "...", requiredClaims = ["tid", "oid"] }
|
|
180
|
-
# ]
|
|
181
|
-
findSubjectByFederatedIdentityUrl = ${?REPOSITORIES_USER_HTTP_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL}
|
|
182
|
-
federatedIdentityLookupCoverage = []
|
|
183
|
-
# Optional. The Store's MFA enrollment witness endpoint: with it, the
|
|
184
|
-
# provider writes whether a subject has a second factor, which keeps a
|
|
185
|
-
# lost factor store from opening a first binding; without it, a boot
|
|
186
|
-
# with MFA on warns (`mfa_enrollment_witness_unwritable`). The Store
|
|
187
|
-
# must then answer `mfaEnrolled` on both authenticate URLs.
|
|
188
|
-
markMfaEnrolledUrl = ${?REPOSITORIES_USER_HTTP_MARK_MFA_ENROLLED_URL}
|
|
189
|
-
# Optional. Sent on every Store request as `Authorization: Bearer
|
|
190
|
-
# <token>`, so the Store can refuse any caller but this deployment;
|
|
191
|
-
# unset, none is sent. A bare token (no "Bearer " prefix) of at least 32
|
|
192
|
-
# bytes of key material -- `openssl rand -hex 32`. Boot fails on a weak,
|
|
193
|
-
# malformed or blank value. One token goes to every URL above.
|
|
194
|
-
bearerToken = ${?REPOSITORIES_USER_HTTP_BEARER_TOKEN}
|
|
195
|
-
# Positive integer, milliseconds, <= 2147483647.
|
|
196
|
-
timeout = 5000
|
|
197
|
-
timeout = ${?REPOSITORIES_USER_HTTP_TIMEOUT}
|
|
198
|
-
# Largest upstream response body accepted, in bytes. Positive integer.
|
|
199
|
-
maxResponseBytes = 1048576
|
|
200
|
-
maxResponseBytes = ${?REPOSITORIES_USER_HTTP_MAX_RESPONSE_BYTES}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
# `standalone-in-memory-code-repository`: the in-process authorization-code
|
|
206
|
-
# repository (`adapters.codeRepository = "memory"`), single-replica only. Its
|
|
207
|
-
# codes' default lifetime, in positive whole seconds.
|
|
208
|
-
standalone-in-memory-code-repository {
|
|
209
|
-
defaultExpiresIn = 600
|
|
210
|
-
defaultExpiresIn = ${?STANDALONE_IN_MEMORY_CODE_REPOSITORY_DEFAULT_EXPIRES_IN}
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
# `audit-sink`: each sink's options, under the sink's name, for the sink
|
|
214
|
-
# `adapters.auditSink` selects -- `audit-sink { splunk-hec { ... } }` for a sink
|
|
215
|
-
# a deployment registers in the audit-sink module (src/modules.mts). The
|
|
216
|
-
# template's `logger` and core's `console` take none.
|
|
217
|
-
audit-sink {}
|
|
218
|
-
|
|
219
|
-
# `adapters`: the composition root's own section -- which adapter fills each
|
|
220
|
-
# slot. The template reads it before it chooses its modules, and hands it to
|
|
221
|
-
# no module. Each value is what the template ships.
|
|
222
|
-
#
|
|
223
|
-
# More than one replica needs every shared store on Redis: `memory` forks per
|
|
224
|
-
# replica, and `core.deployment.mode = "multi"` refuses each memory store by
|
|
225
|
-
# name. Each Redis store shares the one socket `redis-clients` opens.
|
|
226
|
-
adapters {
|
|
227
|
-
# The rate-limit counters: the OAuth endpoints' and the MFA routes'.
|
|
228
|
-
rateLimiter = "memory"
|
|
229
|
-
rateLimiter = ${?ADAPTERS_RATE_LIMITER}
|
|
230
|
-
# The counter behind /session/login's own attempt limit
|
|
231
|
-
# (session.rateLimit.login), and device verification's
|
|
232
|
-
# (device-grant.rateLimit) when the device grant is added. `memory` wires
|
|
233
|
-
# none: each counts per process, which `core.deployment.mode = "multi"`
|
|
234
|
-
# refuses. `redis` needs a server whose maxmemory-policy is `noeviction`.
|
|
235
|
-
attemptCounter = "memory"
|
|
236
|
-
attemptCounter = ${?ADAPTERS_ATTEMPT_COUNTER}
|
|
237
|
-
# The four user-session stores and the subject-level revocation pair. They
|
|
238
|
-
# must be on Redis whenever express-session's store is, or a restart leaves
|
|
239
|
-
# every browser a session whose user session is gone.
|
|
240
|
-
userSessionStores = "memory"
|
|
241
|
-
userSessionStores = ${?ADAPTERS_USER_SESSION_STORES}
|
|
242
|
-
# The RFC 7009 access-token denylist, which POST /oauth/revoke writes and
|
|
243
|
-
# verification reads. On Redis, so a token revoked on one replica is revoked
|
|
244
|
-
# on every one.
|
|
245
|
-
accessTokenDenylist = "redis"
|
|
246
|
-
accessTokenDenylist = ${?ADAPTERS_ACCESS_TOKEN_DENYLIST}
|
|
247
|
-
# The `jti` single-use record behind private_key_jwt client authentication.
|
|
248
|
-
replaySeenSet = "redis"
|
|
249
|
-
replaySeenSet = ${?ADAPTERS_REPLAY_SEEN_SET}
|
|
250
|
-
# Consent to a client that is not first-party: "none" wires no store and
|
|
251
|
-
# such clients are refused at /authorize; "memory" is single-replica only;
|
|
252
|
-
# "redis" keeps the consent records and parked requests on the shared
|
|
253
|
-
# socket (key namespace REDIS_CONSENT_STORE_KEY_PREFIX).
|
|
254
|
-
consentStore = "none"
|
|
255
|
-
consentStore = ${?ADAPTERS_CONSENT_STORE}
|
|
256
|
-
# The upstream IdP tokens held for a session. "redis" needs its encryption
|
|
257
|
-
# key, REDIS_FEDERATION_TOKEN_STORE_ENCRYPTION_KEY.
|
|
258
|
-
federationTokenStore = "memory"
|
|
259
|
-
federationTokenStore = ${?ADAPTERS_FEDERATION_TOKEN_STORE}
|
|
260
|
-
# Federation grants and acquisition's records, read only while
|
|
261
|
-
# `federation-grants.enabled`: "none" (the default) wires no store, and an
|
|
262
|
-
# enabled feature refuses boot naming the one it lacks; "memory" is
|
|
263
|
-
# single-replica only; "redis" is the shared socket. Redis grants need the
|
|
264
|
-
# subject boundary in Redis too (`userSessionStores = "redis"`): boot
|
|
265
|
-
# refuses the pairing with a memory one.
|
|
266
|
-
federationGrantStore = "none"
|
|
267
|
-
federationGrantStore = ${?ADAPTERS_FEDERATION_GRANT_STORE}
|
|
268
|
-
federationGrantIntentStore = "none"
|
|
269
|
-
federationGrantIntentStore = ${?ADAPTERS_FEDERATION_GRANT_INTENT_STORE}
|
|
270
|
-
# Where MFA factors ("memory", "redis" or "store") and MFA transactions
|
|
271
|
-
# ("memory" or "redis") are kept, for a composition that installs MFA.
|
|
272
|
-
mfaFactorStore = "memory"
|
|
273
|
-
mfaFactorStore = ${?ADAPTERS_MFA_FACTOR_STORE}
|
|
274
|
-
mfaTransactionStore = "memory"
|
|
275
|
-
mfaTransactionStore = ${?ADAPTERS_MFA_TRANSACTION_STORE}
|
|
276
|
-
# The authorization-code repository ("memory" loses codes on restart and
|
|
277
|
-
# across replicas).
|
|
278
|
-
codeRepository = "redis"
|
|
279
|
-
codeRepository = ${?ADAPTERS_CODE_REPOSITORY}
|
|
280
|
-
# The client registry (YAML), and the user repository: the Store's HTTP
|
|
281
|
-
# endpoints, or a YAML directory.
|
|
282
|
-
clientRepository = "yaml"
|
|
283
|
-
clientRepository = ${?ADAPTERS_CLIENT_REPOSITORY}
|
|
284
|
-
userRepository = "http"
|
|
285
|
-
userRepository = ${?ADAPTERS_USER_REPOSITORY}
|
|
286
|
-
# Where the audit trail goes: "logger" writes each event through the pino
|
|
287
|
-
# stream every other line takes; core's "console" writes the bare event.
|
|
288
|
-
# There is no "none": a name no sink is registered under refuses boot.
|
|
289
|
-
auditSink = "logger"
|
|
290
|
-
auditSink = ${?ADAPTERS_AUDIT_SINK}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
# `mfaMode`: the composition root's own key -- whether the template installs
|
|
294
|
-
# MFA. Read before it chooses its modules, and handed to no module, as
|
|
295
|
-
# `adapters` is. "required" (the default: every password login has a second
|
|
296
|
-
# factor) and "optional" (users with a factor are challenged) install the MFA
|
|
297
|
-
# package's modules over the two MFA stores above, declare `mfa` in
|
|
298
|
-
# core.sessionRequirements.expected and write `mfa.mode` from this; "off"
|
|
299
|
-
# installs nothing of MFA. Anything else is refused before boot. A
|
|
300
|
-
# configuration that writes `mfa.mode` itself must write what this says, or
|
|
301
|
-
# boot is refused.
|
|
302
|
-
#
|
|
303
|
-
# With MFA on outside development, it needs its two stores on "redis" (or the
|
|
304
|
-
# factors in the "store"), MFA_ENCRYPTION_KEY, an SMTP relay
|
|
305
|
-
# (STANDARD_SMTP_MAIL_SENDER_HOST and _FROM) or the deployment's own mail
|
|
306
|
-
# sender, and a page served at MFA_PAGE_URL (/mfa unless set); a deployment
|
|
307
|
-
# that wants none of it sets MFA_MODE=off.
|
|
308
|
-
mfaMode = "required"
|
|
309
|
-
mfaMode = ${?MFA_MODE}
|
|
310
|
-
|
|
311
|
-
# The MFA routes' budget: the one setting this file writes in sections of
|
|
312
|
-
# modules other than the template's own. Every /session/mfa POST is limited
|
|
313
|
-
# per client address under the prefix `mfa` (`mfa:ip:<ip>`) by the wired
|
|
314
|
-
# limiter alone: the MFA package ships no budget of its own. Both limiters
|
|
315
|
-
# carry it, so switching `adapters.rateLimiter` keeps it; written here, beside
|
|
316
|
-
# each package's own defaults, the limiter not wired has it as a default
|
|
317
|
-
# rather than as a setting nothing reads. Without an entry the limiter's
|
|
318
|
-
# `defaultLimit` (60 per 60 s) applies. The MFA lock is separate and unchanged.
|
|
319
|
-
core-rate-limiter-memory.limits.mfa { limit = 60, windowSeconds = 300 }
|
|
320
|
-
redis-rate-limiter.limits.mfa { limit = 60, windowSeconds = 300 }
|
|
321
|
-
|
|
322
|
-
# The old paths of these sections refuse boot naming the new ones: `cors`,
|
|
323
|
-
# `oauth.jwt.signingKey`, `refreshTokenFamilyStore.redis`,
|
|
324
|
-
# `repositories.code` and `audit.sink`; the old adapter switches
|
|
325
|
-
# (`rateLimiter.adapter`, `oauth.code.adapter`, ...) are refused before the
|
|
326
|
-
# modules are chosen, and so are the variables renamed with them. What the
|
|
327
|
-
# resolution saw of each variable they renamed: each name null, then its value
|
|
328
|
-
# when set. Boot refuses an old name set, whether or not its new name is set,
|
|
329
|
-
# and removes this section before it parses the configuration.
|
|
330
|
-
# Never write it in another layer.
|
|
331
|
-
renamed-variables {
|
|
332
|
-
LOG_LEVEL = null
|
|
333
|
-
LOG_LEVEL = ${?LOG_LEVEL}
|
|
334
|
-
LOGGING_LEVEL = null
|
|
335
|
-
LOGGING_LEVEL = ${?LOGGING_LEVEL}
|
|
336
|
-
CORS_ALLOWED_ORIGINS = null
|
|
337
|
-
CORS_ALLOWED_ORIGINS = ${?CORS_ALLOWED_ORIGINS}
|
|
338
|
-
HTTP_CORS_ALLOWED_ORIGINS = null
|
|
339
|
-
HTTP_CORS_ALLOWED_ORIGINS = ${?HTTP_CORS_ALLOWED_ORIGINS}
|
|
340
|
-
OAUTH_JWT_SIGNING_KEY_PROVIDER = null
|
|
341
|
-
OAUTH_JWT_SIGNING_KEY_PROVIDER = ${?OAUTH_JWT_SIGNING_KEY_PROVIDER}
|
|
342
|
-
KEY_STORE_PROVIDER = null
|
|
343
|
-
KEY_STORE_PROVIDER = ${?KEY_STORE_PROVIDER}
|
|
344
|
-
OAUTH_JWT_ALGORITHM = null
|
|
345
|
-
OAUTH_JWT_ALGORITHM = ${?OAUTH_JWT_ALGORITHM}
|
|
346
|
-
KEY_STORE_LOCAL_ALGORITHM = null
|
|
347
|
-
KEY_STORE_LOCAL_ALGORITHM = ${?KEY_STORE_LOCAL_ALGORITHM}
|
|
348
|
-
OAUTH_JWT_KID = null
|
|
349
|
-
OAUTH_JWT_KID = ${?OAUTH_JWT_KID}
|
|
350
|
-
KEY_STORE_LOCAL_KID = null
|
|
351
|
-
KEY_STORE_LOCAL_KID = ${?KEY_STORE_LOCAL_KID}
|
|
352
|
-
OAUTH_JWT_SECRET = null
|
|
353
|
-
OAUTH_JWT_SECRET = ${?OAUTH_JWT_SECRET}
|
|
354
|
-
KEY_STORE_LOCAL_SECRET = null
|
|
355
|
-
KEY_STORE_LOCAL_SECRET = ${?KEY_STORE_LOCAL_SECRET}
|
|
356
|
-
OAUTH_JWT_PRIVATE_KEY_PATH = null
|
|
357
|
-
OAUTH_JWT_PRIVATE_KEY_PATH = ${?OAUTH_JWT_PRIVATE_KEY_PATH}
|
|
358
|
-
KEY_STORE_LOCAL_PRIVATE_KEY_PATH = null
|
|
359
|
-
KEY_STORE_LOCAL_PRIVATE_KEY_PATH = ${?KEY_STORE_LOCAL_PRIVATE_KEY_PATH}
|
|
360
|
-
OAUTH_JWT_PUBLIC_KEY_PATH = null
|
|
361
|
-
OAUTH_JWT_PUBLIC_KEY_PATH = ${?OAUTH_JWT_PUBLIC_KEY_PATH}
|
|
362
|
-
KEY_STORE_LOCAL_PUBLIC_KEY_PATH = null
|
|
363
|
-
KEY_STORE_LOCAL_PUBLIC_KEY_PATH = ${?KEY_STORE_LOCAL_PUBLIC_KEY_PATH}
|
|
364
|
-
OAUTH_JWT_PRIVATE_KEY = null
|
|
365
|
-
OAUTH_JWT_PRIVATE_KEY = ${?OAUTH_JWT_PRIVATE_KEY}
|
|
366
|
-
KEY_STORE_LOCAL_PRIVATE_KEY = null
|
|
367
|
-
KEY_STORE_LOCAL_PRIVATE_KEY = ${?KEY_STORE_LOCAL_PRIVATE_KEY}
|
|
368
|
-
OAUTH_JWT_PUBLIC_KEY = null
|
|
369
|
-
OAUTH_JWT_PUBLIC_KEY = ${?OAUTH_JWT_PUBLIC_KEY}
|
|
370
|
-
KEY_STORE_LOCAL_PUBLIC_KEY = null
|
|
371
|
-
KEY_STORE_LOCAL_PUBLIC_KEY = ${?KEY_STORE_LOCAL_PUBLIC_KEY}
|
|
372
|
-
REFRESH_TOKEN_FAMILY_STORE_REDIS_URL = null
|
|
373
|
-
REFRESH_TOKEN_FAMILY_STORE_REDIS_URL = ${?REFRESH_TOKEN_FAMILY_STORE_REDIS_URL}
|
|
374
|
-
REDIS_CLIENTS_URL = null
|
|
375
|
-
REDIS_CLIENTS_URL = ${?REDIS_CLIENTS_URL}
|
|
376
|
-
REFRESH_TOKEN_FAMILY_STORE_REDIS_PASSWORD = null
|
|
377
|
-
REFRESH_TOKEN_FAMILY_STORE_REDIS_PASSWORD = ${?REFRESH_TOKEN_FAMILY_STORE_REDIS_PASSWORD}
|
|
378
|
-
REDIS_CLIENTS_PASSWORD = null
|
|
379
|
-
REDIS_CLIENTS_PASSWORD = ${?REDIS_CLIENTS_PASSWORD}
|
|
380
|
-
CLIENT_PATH = null
|
|
381
|
-
CLIENT_PATH = ${?CLIENT_PATH}
|
|
382
|
-
REPOSITORIES_CLIENT_YAML_PATH = null
|
|
383
|
-
REPOSITORIES_CLIENT_YAML_PATH = ${?REPOSITORIES_CLIENT_YAML_PATH}
|
|
384
|
-
CLIENT_USER_PATH = null
|
|
385
|
-
CLIENT_USER_PATH = ${?CLIENT_USER_PATH}
|
|
386
|
-
REPOSITORIES_USER_YAML_PATH = null
|
|
387
|
-
REPOSITORIES_USER_YAML_PATH = ${?REPOSITORIES_USER_YAML_PATH}
|
|
388
|
-
CLIENT_USER_AUTHENTICATE_URL = null
|
|
389
|
-
CLIENT_USER_AUTHENTICATE_URL = ${?CLIENT_USER_AUTHENTICATE_URL}
|
|
390
|
-
REPOSITORIES_USER_HTTP_AUTHENTICATE_URL = null
|
|
391
|
-
REPOSITORIES_USER_HTTP_AUTHENTICATE_URL = ${?REPOSITORIES_USER_HTTP_AUTHENTICATE_URL}
|
|
392
|
-
CLIENT_USER_AUTHENTICATE_BY_TOKEN_URL = null
|
|
393
|
-
CLIENT_USER_AUTHENTICATE_BY_TOKEN_URL = ${?CLIENT_USER_AUTHENTICATE_BY_TOKEN_URL}
|
|
394
|
-
REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL = null
|
|
395
|
-
REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL = ${?REPOSITORIES_USER_HTTP_AUTHENTICATE_BY_TOKEN_URL}
|
|
396
|
-
CLIENT_USER_LINK_FEDERATED_IDENTITY_URL = null
|
|
397
|
-
CLIENT_USER_LINK_FEDERATED_IDENTITY_URL = ${?CLIENT_USER_LINK_FEDERATED_IDENTITY_URL}
|
|
398
|
-
REPOSITORIES_USER_HTTP_LINK_FEDERATED_IDENTITY_URL = null
|
|
399
|
-
REPOSITORIES_USER_HTTP_LINK_FEDERATED_IDENTITY_URL = ${?REPOSITORIES_USER_HTTP_LINK_FEDERATED_IDENTITY_URL}
|
|
400
|
-
CLIENT_USER_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL = null
|
|
401
|
-
CLIENT_USER_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL = ${?CLIENT_USER_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL}
|
|
402
|
-
REPOSITORIES_USER_HTTP_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL = null
|
|
403
|
-
REPOSITORIES_USER_HTTP_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL = ${?REPOSITORIES_USER_HTTP_FIND_SUBJECT_BY_FEDERATED_IDENTITY_URL}
|
|
404
|
-
CLIENT_USER_BEARER_TOKEN = null
|
|
405
|
-
CLIENT_USER_BEARER_TOKEN = ${?CLIENT_USER_BEARER_TOKEN}
|
|
406
|
-
REPOSITORIES_USER_HTTP_BEARER_TOKEN = null
|
|
407
|
-
REPOSITORIES_USER_HTTP_BEARER_TOKEN = ${?REPOSITORIES_USER_HTTP_BEARER_TOKEN}
|
|
408
|
-
CLIENT_USER_TIMEOUT = null
|
|
409
|
-
CLIENT_USER_TIMEOUT = ${?CLIENT_USER_TIMEOUT}
|
|
410
|
-
REPOSITORIES_USER_HTTP_TIMEOUT = null
|
|
411
|
-
REPOSITORIES_USER_HTTP_TIMEOUT = ${?REPOSITORIES_USER_HTTP_TIMEOUT}
|
|
412
|
-
CLIENT_USER_MAX_RESPONSE_BYTES = null
|
|
413
|
-
CLIENT_USER_MAX_RESPONSE_BYTES = ${?CLIENT_USER_MAX_RESPONSE_BYTES}
|
|
414
|
-
REPOSITORIES_USER_HTTP_MAX_RESPONSE_BYTES = null
|
|
415
|
-
REPOSITORIES_USER_HTTP_MAX_RESPONSE_BYTES = ${?REPOSITORIES_USER_HTTP_MAX_RESPONSE_BYTES}
|
|
416
|
-
CLIENT_CODE_DEFAULT_EXPIRES_IN = null
|
|
417
|
-
CLIENT_CODE_DEFAULT_EXPIRES_IN = ${?CLIENT_CODE_DEFAULT_EXPIRES_IN}
|
|
418
|
-
STANDALONE_IN_MEMORY_CODE_REPOSITORY_DEFAULT_EXPIRES_IN = null
|
|
419
|
-
STANDALONE_IN_MEMORY_CODE_REPOSITORY_DEFAULT_EXPIRES_IN = ${?STANDALONE_IN_MEMORY_CODE_REPOSITORY_DEFAULT_EXPIRES_IN}
|
|
420
|
-
CLIENT_CODE_ENDPOINT_URI = null
|
|
421
|
-
CLIENT_CODE_ENDPOINT_URI = ${?CLIENT_CODE_ENDPOINT_URI}
|
|
422
|
-
CLIENT_CODE_PASSWORD = null
|
|
423
|
-
CLIENT_CODE_PASSWORD = ${?CLIENT_CODE_PASSWORD}
|
|
424
|
-
}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
# Mailpit for the SMTP mail sender: a DEVELOPMENT overlay on
|
|
2
|
-
# docker-compose.yml, for a run with MFA on (the template's default, or
|
|
3
|
-
# MFA_MODE in .env) whose mail you can read.
|
|
4
|
-
#
|
|
5
|
-
# docker compose -f docker-compose.yml -f docker-compose.mailpit.yml up --build
|
|
6
|
-
#
|
|
7
|
-
# Write MFA_ENCRYPTION_KEY into .env first (openssl rand -base64 32): this run
|
|
8
|
-
# reads its MFA key from it, not the development sample key.
|
|
9
|
-
#
|
|
10
|
-
# Mailpit keeps every mail the provider sends and delivers none; read them at
|
|
11
|
-
# http://localhost:8025. Never use it in production, where
|
|
12
|
-
# STANDARD_SMTP_MAIL_SENDER_* name a real relay. Leave every
|
|
13
|
-
# STANDARD_SMTP_MAIL_SENDER_* unset in .env for this run, USER and PASSWORD
|
|
14
|
-
# included: the overlay sets HOST, PORT, SECURE and FROM, not the credentials.
|
|
15
|
-
#
|
|
16
|
-
# The SMTP sender sends in plaintext (`none`) only to a loopback host, so
|
|
17
|
-
# Mailpit shares the app container's network namespace and listens on its
|
|
18
|
-
# localhost, and the app service publishes Mailpit's web UI. The configuration
|
|
19
|
-
# is selected as `mailpit` (config/mailpit.conf, the development overlay
|
|
20
|
-
# under another name), since under `development` the template installs the
|
|
21
|
-
# sender that logs each code instead. Under that name the MFA stores may not
|
|
22
|
-
# be kept in memory, so both are on the Redis docker-compose.yml runs.
|
|
23
|
-
|
|
24
|
-
services:
|
|
25
|
-
app:
|
|
26
|
-
ports:
|
|
27
|
-
- "127.0.0.1:8025:8025"
|
|
28
|
-
environment:
|
|
29
|
-
CONFIG_ENV: mailpit
|
|
30
|
-
ADAPTERS_MFA_FACTOR_STORE: redis
|
|
31
|
-
ADAPTERS_MFA_TRANSACTION_STORE: redis
|
|
32
|
-
STANDARD_SMTP_MAIL_SENDER_HOST: localhost
|
|
33
|
-
STANDARD_SMTP_MAIL_SENDER_PORT: "1025"
|
|
34
|
-
STANDARD_SMTP_MAIL_SENDER_SECURE: none
|
|
35
|
-
STANDARD_SMTP_MAIL_SENDER_FROM: auth@example.com
|
|
36
|
-
|
|
37
|
-
mailpit:
|
|
38
|
-
image: axllent/mailpit:v1.31.3
|
|
39
|
-
network_mode: service:app
|