Skip to content

Masks::Rails

The consumer half: a Rails engine that mounts the code flow into an application, so signing in against a masks issuer is configuration rather than a controller you write.

It loads only when Rails::Engine is already defined. Requiring the gem from a plain Ruby process gets Masks::Client and nothing else.

Three pieces do the work:

  • Configuration — the issuer, credentials and routes, set once in an initializer

  • Authentication — masks_login_url, the callback, and the session

  • ProtectedResource — the other direction — checking a bearer this app was

    handed, for an API rather than a browser

This engine is the client. The provider is the masks-server gem, whether it runs elsewhere or is mounted on a subdomain of this app.

Generated from client/lib by bundle exec rake reference. Its shape is the code’s; the prose is the RDoc in the source.

Constant Value
REQUESTS "masks_requests".freeze
HANDSHAKES "masks_handshakes".freeze
FAREWELLS "masks_farewells".freeze
STEPPED_UP "masks_stepped_up".freeze
STEP_UP_WITHIN 300
IDENTITY [ "sub", "sid", "name", "preferred_username", "email", "email_verified", "tenant", "picture", Masks::Client::Claims::AVATARS, Masks::Client::Claims::ORGANIZATION, Masks::Client::Claims::ORGANIZATIONS ].freeze
#authenticate_masks!()
#masked()
#masks_account_url()
#masks_cache()
#masks_configured?()
#masks_disconnect!()
#masks_farewells()
#masks_forget()
#masks_handshake_path()
#masks_handshakes()
#masks_held()
#masks_identity_from(tokens)
#masks_login_url(return_to: nil, organization: nil, privilege: nil, max_age: nil)

Where to send someone to sign in. max_age asks masks for a sign-in no older than that many seconds; an older one is refused at the callback.

#masks_reconnect!()
#masks_refresh!()
#masks_refreshed_identity(tokens)
#masks_registered?()
#masks_registration()
#masks_requests()
#masks_session()
#masks_session_cookies()
#masks_signed_in?()
#masks_store(tokens, identity: nil)
#masks_tokens()
#masks_tracker(key)
Constant Value
CLAIM 30
RESULT 60
WAIT 0.05
PATIENCE 30
LOGOUT 600
LOGOUT_LEEWAY 120
DEPARTURE 30 * 24 * 3600
CIPHER "aes-256-gcm".freeze
NONCE 12
TAG 16
Attribute Access
store R
::key(*parts)
::new(store)
::now()
#depart!(issuer, logout)
#departed?(issuer, identity, since:)
#first?(key, expires_in:)
#first_logout?(issuer, logout)
#renew(issuer, refresh_token)

Inherits Masks::Client::Error.

#masks_config()
Constant Value
Privilege Struct.new(:name, :scopes, :roles, :organization, keyword_init: true)
PRIVILEGE_KEYS %w[scope role organization].freeze
Attribute Access
after_sign_in RW
after_sign_out RW
authenticate_everything RW
cache W
credentials W
credentials_path RW
delegates RW
delegation_redirect_uri W
forget W
issuer W
logged_out W
manages W
name W
namespace RW
organization W
parent_controller RW
privileges R
redirect_uri W
resource RW
resource_scopes RW
scope RW
session_key RW
sign_out_of_issuer RW
store W
::new()
#approved_scope()
#backchannel_logout_uri_for(request)
#cache()
#can_forget?()
#client_id_for(request)
#client_secret_for(request)
#configured?(request)
#credentials_for(request)
#default_credentials()
#delegation_redirect_uri_for(request)
#forget!(request)
#handshake_for(request)
#issuer_for(request)
#logged_out!(request, logout)
#manages?(request, masked = nil)
#name_for(request)
#organization_for(request)
#post_logout_redirect_uri_for(request)
#privilege(name)
#privileges=(value)
#redirect_uri_for(request)
#resource_for(request)
#resource_server_for(request)
#return_to_for(request)
#scope_for(requested)
#session_for(request)
#store!(request, registration)

Inherits Masks::Client::Error.

Constant Value
KEYS %w[client_id client_secret registration_access_token registration_client_uri].freeze
Attribute Access
path R
::new(path)
#clear!()
#connected?()
#read()
#write(registration)

Inherits Rails::Engine.

Attribute Access
access_token R
account_url R
claims R
expires_at R
scopes R
::new(claims:, scopes:, config:, signed_in:, access_token: nil, expires_at: nil, account_url: nil)
::nobody(config)

#[]

#[](claim)
#avatars()
#email()
#email_verified?()
#holds?(privilege)
#member!(privilege)
#name()
#nickname()
#organization()
#organizations()
#permits?(scope)
#picture()
#privilege?(*names)
#privileges()
#role?(*roles)
#signed_in?()
#subject()
#tenant()
#to_h()
::masked!(*privileges, **options)
#authorize_masks!(*names)
#masked()
#masks_authenticate(scope: nil, role: nil, organization: nil)
#masks_challenge(error)
#masks_proof()
#masks_resource()
#masks_resource_metadata()
#masks_unavailable()
Constant Value
OUTCOMES %i[renewed refused unregistered unreachable].freeze
Attribute Access
identity R
outcome R
tokens R
::from_h(body)
::new(outcome, tokens: nil, identity: nil)
::refused()
::renewed(tokens, identity)
::unreachable()
::unregistered()
#to_h()
Constant Value
VERSION "v1".freeze
PIECE 3800
PIECES 8
CIPHER "aes-256-gcm".freeze
NONCE 12
TAG 16
PURPOSE "masks session cookie".freeze
UNPACKED PIECE * PIECES * 8
::key()
::new(request, key)
::open(value, bound)
::seal(held, bound)
#clear()
#name(index)
#read()
#write(held)

Inherits Masks::Client::Error.