mirror of
https://github.com/luxfi/aml.git
synced 2026-09-24 00:25:20 +00:00
The tenant key was the bare org, and an org name is unique within an issuer
rather than across issuers. `acme` on lux.id and `acme` on zoolabs.id are two
unrelated financial institutions, and every store keyed them as one — including
the tokenisation vault, where the org WAS the HKDF salt (pkg/token New). Two
brands therefore derived the same keys: one institution's customer names
tokenised to the other's pseudonyms, and its sealed records opened under the
other's tenant. That is a plaintext cross-brand disclosure of retained personal
data, against the purpose limitation retention exists under (Directive (EU)
2015/849 Art. 41(2)) and against HIP-0302. It is fixed now, before any record
exists, because doing it later re-keys every vault.
The tenant is now `<brand>/<org>`, minted in one place (api/tenant.go qualify)
and checked where it crosses into the store, the history column and the salt.
Both Identity implementations produce the same key: the brand comes from the
request's own Host in both, never from a header a client can write.
The auth path is now the caller that refuses rather than defaulting:
- brand.ForHost is gone, with brand.Default and brand.IssuerFor. While a
defaulting resolver existed the auth path used it, so hanzo.id
authenticated callers on every Host nobody claimed — a pod IP, a
*.svc.cluster.local name, localhost through a port-forward, an absent Host,
a misrouted vhost. brand.For reports ok, and there is no fallback to reach.
- `aud` must contain this deployment's IAM clientId (AML_CLIENT_ID, no
default, refuses to start without it). IAM stamps aud = the app's clientId,
so with no pin any first-party token from the same issuer was a credential
here, including one minted for a marketing site. RFC 9068 §4.
- `tokenType` must be "access-token". An id_token carries the same iss and
aud and is issued to a browser, not to an API caller.
- `owner` must be an org the caller is a member of, when the token carries a
membership set. IAM stamps the APP's org as `owner` (internal/oidc/jwt.go
Sign), so a shared or org-choice application would make every one of its
users one tenant. IAM refuses a cross-org login for a dedicated app
(internal/oidc/login.go), which is what makes the claim correct for the
shape this supports: one application per institution.
- a bearer that is not a compact JWS is refused before any keyset is
resolved, so an unauthenticated caller cannot spend a network round trip.
Keys, in api/jwks.go with the algorithms that accept them, because the two
lists have to agree:
- one lock per issuer, taken outside the map, so an issuer that does not
answer holds up only itself. One process-wide mutex held across the HTTP
fetch meant a single unreachable issuer — selected by a caller's Host —
serialised every request in the process behind it.
- a failed fetch is remembered briefly, so an unreachable issuer costs one
attempt per window instead of one per request.
- EC (ES256/384/512) and ML-DSA-65 verify, which is what IAM publishes
besides RSA (internal/oidc/jwks.go signingAlgs). A dropped key type is a
silent lockout of a whole brand, so a key that cannot be loaded now names
its kty and alg in the log.
Also here: caseOf returned refuse()'s value as an error, and refuse() returns
nil once it has answered the request — so an unauthenticated POST to a case
route dereferenced a nil case. It reports errNoCase and writes nothing.
Transaction.TenantID is deleted: a second tenant field nothing reads is an
invitation to scope data by a value the caller supplies.
Co-authored-by: Hanzo Dev <[email protected]>
124 lines
5.3 KiB
AMPL
124 lines
5.3 KiB
AMPL
module github.com/luxfi/aml
|
|
|
|
go 1.26.4
|
|
|
|
require (
|
|
github.com/expr-lang/expr v1.17.6
|
|
github.com/golang-jwt/jwt/v5 v5.3.1
|
|
github.com/google/uuid v1.6.0
|
|
github.com/hanzoai/base v1.5.8
|
|
github.com/hanzoai/dbx v1.16.0
|
|
github.com/luxfi/crypto v1.20.2
|
|
github.com/spf13/cobra v1.10.2
|
|
golang.org/x/text v0.38.0
|
|
)
|
|
|
|
require (
|
|
filippo.io/edwards25519 v1.2.0 // indirect
|
|
filippo.io/hpke v0.4.0 // indirect
|
|
github.com/ALTree/bigfloat v0.2.0 // indirect
|
|
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect
|
|
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
|
github.com/cloudflare/circl v1.6.3 // indirect
|
|
github.com/cronokirby/saferith v0.33.0 // indirect
|
|
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
|
|
github.com/decred/dcrd/dcrec/secp256k1/v4 v4.4.1 // indirect
|
|
github.com/disintegration/imaging v1.6.2 // indirect
|
|
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
|
|
github.com/dustin/go-humanize v1.0.1 // indirect
|
|
github.com/fatih/color v1.19.0 // indirect
|
|
github.com/fsnotify/fsnotify v1.9.0 // indirect
|
|
github.com/fxamacker/cbor/v2 v2.9.1 // indirect
|
|
github.com/gabriel-vasile/mimetype v1.4.13 // indirect
|
|
github.com/ganigeorgiev/fexpr v0.5.0 // indirect
|
|
github.com/go-ini/ini v1.67.0 // indirect
|
|
github.com/go-jose/go-jose/v4 v4.1.4 // indirect
|
|
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
|
|
github.com/google/go-cmp v0.7.0 // indirect
|
|
github.com/gorilla/rpc v1.2.1 // indirect
|
|
github.com/grandcat/zeroconf v1.0.0 // indirect
|
|
github.com/gtank/merlin v0.1.1 // indirect
|
|
github.com/gtank/ristretto255 v0.2.0 // indirect
|
|
github.com/hanzoai/csqlite v0.1.0 // indirect
|
|
github.com/hanzoai/orm v0.6.10 // indirect
|
|
github.com/hanzoai/pubsub-go v1.0.0 // indirect
|
|
github.com/hanzoai/sqlcipher v0.1.0 // indirect
|
|
github.com/hanzoai/sqlite v0.3.2 // indirect
|
|
github.com/hanzoai/tasks v1.52.0 // indirect
|
|
github.com/holiman/uint256 v1.3.2 // indirect
|
|
github.com/inconshreveable/mousetrap v1.1.0 // indirect
|
|
github.com/jackc/pgpassfile v1.0.0 // indirect
|
|
github.com/jackc/pgservicefile v0.0.0-20240606120523-5a60cdf6a761 // indirect
|
|
github.com/jackc/pgx/v5 v5.9.1 // indirect
|
|
github.com/jackc/puddle/v2 v2.2.2 // indirect
|
|
github.com/klauspost/compress v1.18.6 // indirect
|
|
github.com/klauspost/cpuid/v2 v2.3.0 // indirect
|
|
github.com/klauspost/crc32 v1.3.0 // indirect
|
|
github.com/luxfi/accel v1.2.4 // indirect
|
|
github.com/luxfi/age v1.6.0 // indirect
|
|
github.com/luxfi/cache v1.3.1 // indirect
|
|
github.com/luxfi/consensus v1.36.3 // indirect
|
|
github.com/luxfi/constants v1.6.2 // indirect
|
|
github.com/luxfi/container v0.2.1 // indirect
|
|
github.com/luxfi/corona v0.10.4 // indirect
|
|
github.com/luxfi/dkg v0.3.5 // indirect
|
|
github.com/luxfi/fhe v1.8.8 // indirect
|
|
github.com/luxfi/geth v1.20.1 // indirect
|
|
github.com/luxfi/ids v1.3.2 // indirect
|
|
github.com/luxfi/lattice/v7 v7.1.4 // indirect
|
|
github.com/luxfi/lens v0.2.1 // indirect
|
|
github.com/luxfi/log v1.4.3 // indirect
|
|
github.com/luxfi/magnetar v1.2.3 // indirect
|
|
github.com/luxfi/math v1.5.1 // indirect
|
|
github.com/luxfi/math/big v0.1.0 // indirect
|
|
github.com/luxfi/mdns v0.1.1 // indirect
|
|
github.com/luxfi/metric v1.8.1 // indirect
|
|
github.com/luxfi/mlwe v0.3.0 // indirect
|
|
github.com/luxfi/mock v0.1.1 // indirect
|
|
github.com/luxfi/pq v1.1.0 // indirect
|
|
github.com/luxfi/pulsar v1.9.2 // indirect
|
|
github.com/luxfi/sampler v1.1.0 // indirect
|
|
github.com/luxfi/threshold v1.12.3 // indirect
|
|
github.com/luxfi/zap v1.2.6 // indirect
|
|
github.com/mattn/go-colorable v0.1.15 // indirect
|
|
github.com/mattn/go-isatty v0.0.22 // indirect
|
|
github.com/miekg/dns v1.1.72 // indirect
|
|
github.com/mimoo/StrobeGo v0.0.0-20220103164710-9a04d6ca976b // indirect
|
|
github.com/minio/crc64nvme v1.1.1 // indirect
|
|
github.com/minio/md5-simd v1.1.2 // indirect
|
|
github.com/minio/minio-go/v7 v7.0.100 // indirect
|
|
github.com/montanaflynn/stats v0.9.0 // indirect
|
|
github.com/mr-tron/base58 v1.3.0 // indirect
|
|
github.com/nats-io/nkeys v0.4.15 // indirect
|
|
github.com/nats-io/nuid v1.0.1 // indirect
|
|
github.com/ncruces/go-strftime v1.0.0 // indirect
|
|
github.com/philhofer/fwd v1.2.0 // indirect
|
|
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
|
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
|
|
github.com/robfig/cron/v3 v3.0.1 // indirect
|
|
github.com/rs/xid v1.6.0 // indirect
|
|
github.com/spf13/cast v1.10.0 // indirect
|
|
github.com/spf13/pflag v1.0.10 // indirect
|
|
github.com/stretchr/testify v1.11.1 // indirect
|
|
github.com/supranational/blst v0.3.16 // indirect
|
|
github.com/tinylib/msgp v1.6.4 // indirect
|
|
github.com/x448/float16 v0.8.4 // indirect
|
|
github.com/zeebo/blake3 v0.2.4 // indirect
|
|
go.uber.org/mock v0.6.0 // indirect
|
|
go.yaml.in/yaml/v3 v3.0.4 // indirect
|
|
golang.org/x/crypto v0.53.0 // indirect
|
|
golang.org/x/exp v0.0.0-20260529124908-c761662dc8c9 // indirect
|
|
golang.org/x/image v0.38.0 // indirect
|
|
golang.org/x/mod v0.36.0 // indirect
|
|
golang.org/x/net v0.56.0 // indirect
|
|
golang.org/x/oauth2 v0.36.0 // indirect
|
|
golang.org/x/sync v0.21.0 // indirect
|
|
golang.org/x/sys v0.46.0 // indirect
|
|
golang.org/x/time v0.15.0 // indirect
|
|
golang.org/x/tools v0.45.0 // indirect
|
|
gonum.org/v1/gonum v0.17.0 // indirect
|
|
google.golang.org/protobuf v1.36.11 // indirect
|
|
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
|
)
|