NAME

Airlock::Client - OAuth 2.0 device flow client (RFC 8628)

VERSION

version 0.001

SYNOPSIS

my $client = Airlock::Client->new(
  issuer    => 'https://id.example.org/realms/main',
  client_id => 'my-cli',
  scope     => 'openid profile',
);

my $token = $client->login;      # prints code and QR to STDERR, then waits
print $token->{access_token};

DESCRIPTION

The other side of the device flow: what a command line tool runs to get a token. It starts the flow, shows the person where to go, polls the token endpoint at the pace the server sets, and returns the token response.

It speaks plain RFC 8628 and so works against Airlock, Keycloak, and anything else that implements the grant, including servers that report errors with status 200.

client_id

Required. The client identifier registered with the server.

scope

Scopes to ask for, separated by spaces. Default: none.

issuer

The issuer URL. When given, the endpoints are read from <issuer>/.well-known/openid-configuration.

device_endpoint

The device authorization endpoint. Discovered from issuer unless given.

token_endpoint

The token endpoint. Discovered from issuer unless given.

ua

The HTTP::Tiny to use. The default verifies TLS certificates. HTTPS needs IO::Socket::SSL.

on_prompt

Coderef called with the device authorization response once the flow has started. The default prints "prompt_text" to STDERR.

sleep

Coderef called with the seconds to wait between polls. For tests.

now

Coderef returning the current epoch. For tests.

start

my $start = $client->start;

Begins the flow. Returns the device authorization response: device_code, user_code, verification_uri, optionally verification_uri_complete, expires_in and interval. Croaks when the server refuses.

poll

my $token = $client->poll($start);

Waits for the approval. Sleeps the interval the server asked for, never past the lifetime of the code, adds five seconds on every slow_down and on every connection failure, and returns the token response. Croaks on access_denied, expired_token, any other error, and when the code's lifetime runs out.

login

my $token = $client->login;

"start", the prompt, then "poll".

prompt_text

print STDERR $client->prompt_text($start);

What to show the person: where to go, the code, and a QR code of verification_uri_complete when the server sent one. Takes the options of "terminal" in Airlock::QR.

SUPPORT

Issues

Please report bugs and feature requests on GitHub at https://github.com/Getty/p5-airlock/issues.

IRC

Join #kubernetes on irc.perl.org or message Getty directly.

CONTRIBUTING

Contributions are welcome! Please fork the repository and submit a pull request.

AUTHOR

Torsten Raudssus <getty@cpan.org>

COPYRIGHT AND LICENSE

This software is copyright (c) 2026 by Torsten Raudssus <torsten@raudssus.de> https://raudssus.de/.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.