Class: Leash::Client
- Inherits:
-
Object
- Object
- Leash::Client
- Defined in:
- lib/leash/client.rb
Overview
Unified Leash client — namespaces for ‘auth`, `env`, `integrations`. Ruby mirror of `leash-sdk-ts/src/leash.ts` and `leash-sdk-python/leash/client.py`.
Construction is server-only in 0.4 and requires a request object:
leash = Leash.new(request: request) # Rails / Sinatra / Hanami / Rack hash
user = leash.auth.user # Leash::User or nil
key = leash.env.get("OPENAI_API_KEY") # String or nil
msgs = leash.integrations.gmail.(max_results: 5)
Authentication precedence (mirror TS / Python / Go exactly):
1. `LEASH_API_KEY` env var (or explicit `api_key:` constructor arg)
2. `Authorization: Bearer <jwt>` header on the request — used for
`auth.user` AND as an env-read fallback (when no API key), but
NEVER forwarded on integration POSTs
3. `leash-auth` cookie from the request
The Bearer fallback for env reads is documented here per the Go-reviewer callout: when the constructor sees no ‘LEASH_API_KEY` but does see an inbound `Authorization: Bearer …`, the bearer JWT is used as the API key for the platform’s ‘/api/apps/me/secrets/` endpoint. The bearer is still suppressed on integration POSTs (Critical #1 in the 0.4 plan).
Defined Under Namespace
Classes: AuthFacade
Instance Attribute Summary collapse
- #auth ⇒ Auth readonly
- #bearer_token ⇒ Object readonly
- #cookie_value ⇒ Object readonly
- #env ⇒ Leash::Env readonly
- #explicit_api_key ⇒ Object readonly
- #integrations ⇒ Leash::Integrations::Namespace readonly
- #platform_url ⇒ String readonly
Instance Method Summary collapse
-
#initialize(request:, platform_url: nil, api_key: nil, transport: nil) ⇒ Client
constructor
A new instance of Client.
Constructor Details
#initialize(request:, platform_url: nil, api_key: nil, transport: nil) ⇒ Client
Returns a new instance of Client.
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/leash/client.rb', line 57 def initialize(request:, platform_url: nil, api_key: nil, transport: nil) if request.nil? raise Error.new( "Leash requires a request object in server environments.", code: "NO_REQUEST_SERVER_CONSTRUCT", action: "Pass request: req to Leash.new in your route handler.", see_also: "https://leash.build/docs/sdk" ) end @request = request @platform_url = (platform_url || ENV["LEASH_PLATFORM_URL"] || DEFAULT_PLATFORM_URL) .to_s.sub(%r{/+\z}, "") # Auth precedence: explicit api_key > LEASH_API_KEY env > bearer header > cookie. env_api_key = ENV["LEASH_API_KEY"] env_api_key = nil if env_api_key && env_api_key.empty? @explicit_api_key = api_key || env_api_key @bearer_token = Auth.extract_bearer_token(request) @cookie_value = Auth.(request) # Bearer→env fallback: when no app key is present, the inbound user # JWT is used to authenticate env reads to the platform. NEVER used # as `X-API-Key` on integration POSTs (see Transport docstring). @env_api_key = @explicit_api_key || @bearer_token @transport = transport || Transport.new( platform_url: @platform_url, api_key: @explicit_api_key, cookie_value: @cookie_value ) @auth = AuthFacade.new(request) @env = Env.new( platform_url: @platform_url, api_key: @env_api_key, transport: @transport ) @integrations = Integrations::Namespace.new(@transport) end |
Instance Attribute Details
#bearer_token ⇒ Object (readonly)
100 101 102 |
# File 'lib/leash/client.rb', line 100 def bearer_token @bearer_token end |
#cookie_value ⇒ Object (readonly)
100 101 102 |
# File 'lib/leash/client.rb', line 100 def @cookie_value end |
#explicit_api_key ⇒ Object (readonly)
100 101 102 |
# File 'lib/leash/client.rb', line 100 def explicit_api_key @explicit_api_key end |
#integrations ⇒ Leash::Integrations::Namespace (readonly)
38 39 40 |
# File 'lib/leash/client.rb', line 38 def integrations @integrations end |
#platform_url ⇒ String (readonly)
47 48 49 |
# File 'lib/leash/client.rb', line 47 def platform_url @platform_url end |