Airlock
view release on metacpan or search on metacpan
docs/superpowers/plans/2026-10-02-airlock-phase-1.md view on Meta::CPAN
};
}
=method subject
my $subject = $keycloak->subject($claims);
The Airlock subject for a set of token claims: C<id> from C<sub>, and C<amr>,
C<acr> and C<auth_time> as Keycloak sent them. Croaks without C<sub>.
=cut
sub factor {
my ( $self, %arg ) = @_;
return $self->factor_class->new( accept_amr => $self->mfa_amr, accept_acr => $self->mfa_acr, %arg );
}
=method factor
my $factor = $keycloak->factor( max_age => 300 );
An L<Airlock::Factor::Upstream> that holds for a Keycloak login with a second
factor. Takes its options.
=cut
1;
```
- [ ] **Step 4: Unit-Test laufen lassen, Modul in den Load-Test**
Run: `prove -lr t/45-upstream-keycloak.t` â Expected: PASS (2 Subtests). Dann ` Airlock::Upstream::Keycloak` in die Liste in `t/00-load.t` und `prove -lr t` â Expected: PASS.
- [ ] **Step 5: Realm, Anleitung und Live-Test schreiben**
`t/keycloak/realm.json`:
```json
{
"realm": "airlock-test",
"enabled": true,
"clients": [
{
"clientId": "airlock-test-cli",
"publicClient": true,
"standardFlowEnabled": false,
"directAccessGrantsEnabled": true,
"attributes": {
"oauth2.device.authorization.grant.enabled": "true"
}
}
],
"users": [
{
"username": "plain",
"enabled": true,
"email": "plain@example.org",
"emailVerified": true,
"firstName": "Plain",
"lastName": "User",
"credentials": [
{ "type": "password", "value": "plain-password", "temporary": false }
]
},
{
"username": "otp",
"enabled": true,
"email": "otp@example.org",
"emailVerified": true,
"firstName": "Otp",
"lastName": "User",
"credentials": [
{ "type": "password", "value": "otp-password", "temporary": false },
{
"type": "otp",
"secretData": "{\"value\":\"12345678901234567890\"}",
"credentialData": "{\"subType\":\"totp\",\"digits\":6,\"counter\":0,\"period\":30,\"algorithm\":\"HmacSHA1\"}"
}
]
}
]
}
```
`t/keycloak/README.md`:
````markdown
# Keycloak live test
`t/90-live-keycloak.t` runs only when `TEST_AIRLOCK_KEYCLOAK_URL` is set. It
needs a Keycloak with the realm `airlock-test` from `realm.json` in this
directory: a public client `airlock-test-cli` with the device authorization
grant and direct access grants enabled, a user `plain` with a password, and a
user `otp` with a password and a TOTP credential whose secret is the RFC 6238
test secret `12345678901234567890`.
## Start a throwaway Keycloak
```bash
docker run --rm --name airlock-keycloak -p 8080:8080 \
-e KC_BOOTSTRAP_ADMIN_USERNAME=admin -e KC_BOOTSTRAP_ADMIN_PASSWORD=admin \
-v "$PWD/t/keycloak/realm.json:/opt/keycloak/data/import/realm.json:ro" \
quay.io/keycloak/keycloak:latest start-dev --import-realm
```
Keycloak needs about 1 GB of memory. Do not start it on a machine that is
already short of it.
## Run
```bash
TEST_AIRLOCK_KEYCLOAK_URL=http://localhost:8080 prove -lv t/90-live-keycloak.t
```
## Findings
Recorded by whoever ran the test last. The `diag` lines of the test print
what to copy here.
| Keycloak version | Login | acr | amr | auth_time |
|---|---|---|---|---|
````
`t/90-live-keycloak.t`:
```perl
#!/usr/bin/env perl
use strict;
use warnings;
use Test::More;
# Live test against a real Keycloak. Off unless TEST_AIRLOCK_KEYCLOAK_URL is
( run in 0.516 second using v1.01-cache-2.11-cpan-3f962061493 )