omniauth-carta 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +21 -0
- data/README.md +196 -0
- data/lib/omniauth/carta/version.rb +7 -0
- data/lib/omniauth/strategies/carta.rb +66 -0
- data/lib/omniauth-carta.rb +4 -0
- metadata +63 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 1102ede87797f5363ec6d747c970aa3f10d7f5d05df1677cc0e16119ee404408
|
|
4
|
+
data.tar.gz: 935505ac178ca89e9076886c496465169f029439028d2b78e958e2585d3a8b35
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: da2ffe66956d0da878acd243a31bc76462e01acaf2a16a02b7ea8f0c073fdfc2237d17c1f3107824687a69b14ef8b7df29f95cbbca5976ce453a0d310d4a956f
|
|
7
|
+
data.tar.gz: 9835272275b508ba9f460e0f1dc43c97d5840868ad9bc91355fc568113246d07ac3e03072539d94430d5095b3f2ae6e9c684b501d936f75cec7584e97354f45c
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.1.0 — 2026-09-09
|
|
4
|
+
|
|
5
|
+
- Add the Carta OmniAuth OAuth2 strategy with HTTP Basic token exchange.
|
|
6
|
+
- Fetch UserInfo for stable subject IDs and optional profile/email fields.
|
|
7
|
+
- Enable S256 PKCE and preserve OmniAuth state and request CSRF protection.
|
|
8
|
+
- Support custom endpoints, scopes, and callback URLs.
|
|
9
|
+
- Add Minitest fixtures, middleware integration tests, and Ruby CI.
|
|
10
|
+
- Preserve Carta-returned scopes in the auth hash credentials.
|
|
11
|
+
- Preserve refresh tokens even when the token response omits expiry information.
|
|
12
|
+
- Verify playground endpoint overrides with API scopes and document the working Rails configuration.
|
|
13
|
+
- Document scope reauthorization, resource permissions, and the application-owned API/refresh boundary.
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Avi Flombaum
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# OmniAuth Carta
|
|
2
|
+
|
|
3
|
+
An [OmniAuth OAuth2](https://github.com/omniauth/omniauth-oauth2) strategy for authenticating Carta users in Ruby and Rails applications. Requires Ruby 3.2+ and OmniAuth 2 (provided by the OAuth2 dependency).
|
|
4
|
+
|
|
5
|
+
The strategy exchanges authorization codes, fetches Carta's UserInfo, and returns the standard OmniAuth auth hash. It enables S256 PKCE and state verification by default.
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add the gem to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem "omniauth-carta", "~> 0.1.0"
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Run `bundle install`. Source code and issues are hosted on [GitHub](https://github.com/aviflombaum/omniauth-carta).
|
|
16
|
+
|
|
17
|
+
## Register with Carta
|
|
18
|
+
|
|
19
|
+
Register an authorization-code application in the [Carta Developer Portal](https://developers.app.carta.com/). Enable `openid`, `profile`, and `email` for the default configuration. Register your exact callback URL, such as `https://your-app.example/auth/carta/callback`, and obtain the client ID and secret. Keep secrets in your application's credentials or environment.
|
|
20
|
+
|
|
21
|
+
See Carta's [authorization guide](https://docs.carta.com/api-platform/guides/guides/authorization/using-the-authorization-code-flow/) and [OIDC guide](https://docs.carta.com/api-platform/guides/references/oidc/).
|
|
22
|
+
|
|
23
|
+
## Rails
|
|
24
|
+
|
|
25
|
+
Add Rails' OmniAuth request CSRF integration:
|
|
26
|
+
|
|
27
|
+
```ruby
|
|
28
|
+
# Gemfile
|
|
29
|
+
gem "omniauth-rails_csrf_protection", "~> 1.0"
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Configure the middleware:
|
|
33
|
+
|
|
34
|
+
```ruby
|
|
35
|
+
# config/initializers/omniauth.rb
|
|
36
|
+
Rails.application.config.middleware.use OmniAuth::Builder do
|
|
37
|
+
provider :carta, Rails.application.credentials.dig(:carta, :client_id),
|
|
38
|
+
Rails.application.credentials.dig(:carta, :client_secret)
|
|
39
|
+
end
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Start authentication with a POST form. Keep Turbo from treating the external redirect as a fetch:
|
|
43
|
+
|
|
44
|
+
```erb
|
|
45
|
+
<%= button_to "Connect Carta", "/auth/carta", method: :post, data: { turbo: false } %>
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Route the callback and failure endpoint to your application:
|
|
49
|
+
|
|
50
|
+
```ruby
|
|
51
|
+
# config/routes.rb
|
|
52
|
+
get "/auth/carta/callback", to: "carta_sessions#create"
|
|
53
|
+
get "/auth/failure", to: "carta_sessions#failure"
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
In `CartaSessionsController#create`, read `request.env.fetch("omniauth.auth")`. Find or create your application account using the provider and UID together; perform account linking according to your application's policy. Store the application's user ID in the session and any Carta tokens in encrypted server-side storage. The failure action should display a generic retry message, without rendering raw provider error details. API-only Rails apps also need cookie/session middleware for OmniAuth.
|
|
57
|
+
|
|
58
|
+
## Plain Ruby / Rack
|
|
59
|
+
|
|
60
|
+
Require `omniauth-carta`, install session middleware before `OmniAuth::Builder`, and register `provider :carta, client_id, client_secret`. Render a POST form with a token from `Rack::Protection::AuthenticityToken.token(env["rack.session"])`. OmniAuth's default request validation checks that token; leave it enabled.
|
|
61
|
+
|
|
62
|
+
The runnable [Rack example](examples/rack/config.ru) demonstrates the complete form, callback, session, and failure flow:
|
|
63
|
+
|
|
64
|
+
```sh
|
|
65
|
+
cd examples/rack
|
|
66
|
+
bundle install
|
|
67
|
+
export CARTA_CLIENT_ID=your-client-id
|
|
68
|
+
export CARTA_CLIENT_SECRET=your-client-secret
|
|
69
|
+
export SESSION_SECRET=$(ruby -rsecurerandom -e 'puts SecureRandom.hex(64)')
|
|
70
|
+
bundle exec rackup -p 9292
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
Register `http://localhost:9292/auth/carta/callback` with your Carta development application and open `http://localhost:9292`. The example displays the UID but does not persist accounts or tokens. Use HTTPS and secure cookies in production.
|
|
74
|
+
|
|
75
|
+
## Options
|
|
76
|
+
|
|
77
|
+
| Option | Default | Purpose |
|
|
78
|
+
| --- | --- | --- |
|
|
79
|
+
| `scope` | `"openid profile email"` | Space-delimited requested scopes |
|
|
80
|
+
| `pkce` | `true` | S256 proof key for code exchange |
|
|
81
|
+
| `userinfo_url` | `"/o/userinfo/"` | Relative to client site, or an absolute URL |
|
|
82
|
+
| `callback_url` | Generated from host and callback path | Explicit registered redirect URI |
|
|
83
|
+
| `client_options[:site]` | `"https://login.app.carta.com"` | OAuth host |
|
|
84
|
+
| `client_options[:authorize_url]` | `"/o/authorize/"` | Authorization endpoint |
|
|
85
|
+
| `client_options[:token_url]` | `"/o/access_token/"` | Token endpoint |
|
|
86
|
+
| `client_options[:auth_scheme]` | `:basic_auth` | Client authentication method |
|
|
87
|
+
|
|
88
|
+
Standard OmniAuth options such as `name`, `path_prefix`, `callback_path`, `authorize_params`, and `setup` also apply. Generated callback URLs omit request query parameters so the token exchange uses the same redirect URI. Use an explicit `callback_url` if the registered URI includes a query string. Configure your application's trusted proxy/host settings correctly when generating URLs behind a proxy.
|
|
89
|
+
|
|
90
|
+
Add only the API scopes your application needs, keeping `openid` for identity lookup:
|
|
91
|
+
|
|
92
|
+
```ruby
|
|
93
|
+
provider :carta, ENV.fetch("CARTA_CLIENT_ID"), ENV.fetch("CARTA_CLIENT_SECRET"),
|
|
94
|
+
scope: "openid profile email read_issuer_info"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Scope values must be enabled for your registered Carta application. `profile` and `email` are optional; `openid` is required to use UserInfo. API permissions remain subject to the consenting user's Carta roles. See [Carta's scope reference](https://docs.carta.com/api-platform/guides/references/scopes/).
|
|
98
|
+
|
|
99
|
+
### Playground
|
|
100
|
+
|
|
101
|
+
New Carta applications use playground credentials until production promotion and approval. This strategy defaults to production, so configure playground endpoints explicitly. The following endpoint configuration was verified with a Rails integration; confirm it against your Developer Portal's Playground tab:
|
|
102
|
+
|
|
103
|
+
```ruby
|
|
104
|
+
provider :carta, ENV.fetch("CARTA_CLIENT_ID"), ENV.fetch("CARTA_CLIENT_SECRET"),
|
|
105
|
+
client_options: {
|
|
106
|
+
site: "https://login.playground.carta.team",
|
|
107
|
+
authorize_url: "https://login.playground.carta.team/o/authorize/",
|
|
108
|
+
token_url: "https://login.playground.carta.team/o/access_token/"
|
|
109
|
+
},
|
|
110
|
+
userinfo_url: "https://login.playground.carta.team/o/userinfo/"
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
The same `/auth/carta/callback` path works in either environment. Its full URL must exactly match the callback registered with the corresponding Carta application, including scheme, hostname, path, and any trailing slash. The client secret is used during token exchange, so an authorization-page rejection can indicate that playground credentials were sent to production or that the registered redirect URI does not match.
|
|
114
|
+
|
|
115
|
+
Use trusted HTTPS endpoint configuration. See [Carta's playground guide](https://docs.carta.com/api-platform/guides/getting-started/playground-environment/).
|
|
116
|
+
|
|
117
|
+
## Auth hash
|
|
118
|
+
|
|
119
|
+
An illustrative successful callback provides:
|
|
120
|
+
|
|
121
|
+
```ruby
|
|
122
|
+
{
|
|
123
|
+
"provider" => "carta",
|
|
124
|
+
"uid" => "carta-user-123", # UserInfo sub; stable identity, not email
|
|
125
|
+
"info" => {
|
|
126
|
+
"name" => "Alex Example",
|
|
127
|
+
"first_name" => "Alex",
|
|
128
|
+
"last_name" => "Example",
|
|
129
|
+
"email" => "alex@example.com"
|
|
130
|
+
},
|
|
131
|
+
"credentials" => {
|
|
132
|
+
"token" => "ACCESS_TOKEN",
|
|
133
|
+
"refresh_token" => "REFRESH_TOKEN",
|
|
134
|
+
"expires_at" => 1_800_000_000,
|
|
135
|
+
"expires" => true,
|
|
136
|
+
"scope" => "openid profile email"
|
|
137
|
+
},
|
|
138
|
+
"extra" => {
|
|
139
|
+
"raw_info" => {
|
|
140
|
+
"sub" => "carta-user-123",
|
|
141
|
+
"name" => "Alex Example",
|
|
142
|
+
"given_name" => "Alex",
|
|
143
|
+
"family_name" => "Example",
|
|
144
|
+
"email" => "alex@example.com"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Profile fields depend on granted scopes and available claims; missing fields are omitted. UserInfo is fetched once per authentication. A missing or invalid `sub` fails authentication. Credentials follow `omniauth-oauth2` conventions. A returned refresh token is preserved even when expiry information is absent. `scope` contains the space-delimited scopes returned in Carta's token response when present; the strategy does not substitute configured/requested scopes when the response omits it. An omitted scope field is not evidence that access was denied. Record requested scopes separately if you need them for diagnostics.
|
|
151
|
+
|
|
152
|
+
Identity comes from an authenticated HTTPS UserInfo request. The strategy does not decode, expose, or validate ID tokens and is not a full OIDC relying-party implementation. Do not treat an unverified ID token or an email address as proof of account ownership.
|
|
153
|
+
|
|
154
|
+
## Using Carta API permissions
|
|
155
|
+
|
|
156
|
+
Identity scopes (`openid profile email`) allow sign-in; they do not authorize portfolio imports. For example, browsing investor companies requires:
|
|
157
|
+
|
|
158
|
+
```ruby
|
|
159
|
+
scope: "openid profile email read_investor_firms read_investor_funds read_investor_investments"
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
Add the read scopes needed for cap tables, securities, or valuations to your application's request. Enabling a scope in the Carta portal does not add it to an existing access token: reconnect the user after expanding the requested scopes. A successful OAuth callback does not guarantee access to every API resource; resource access also depends on the consenting user's permissions and selected resources. Handle API authorization failures in your application.
|
|
163
|
+
|
|
164
|
+
Keep Carta API clients, pagination, fund/company mappings, import persistence, and refresh coordination in the consuming application. This gem's contract is the OAuth strategy and auth hash. The Rails integration verified investor firms/funds/investments, shareholder portfolios, and managed issuers through separate application-level API calls; those resources are not part of the gem.
|
|
165
|
+
|
|
166
|
+
## Refreshing API access
|
|
167
|
+
|
|
168
|
+
OmniAuth handles login; your application manages subsequent API calls and token refresh. Reuse the OAuth2 client with the same endpoint configuration:
|
|
169
|
+
|
|
170
|
+
```ruby
|
|
171
|
+
strategy = OmniAuth::Strategies::Carta.new(nil,
|
|
172
|
+
ENV.fetch("CARTA_CLIENT_ID"), ENV.fetch("CARTA_CLIENT_SECRET"))
|
|
173
|
+
token = OAuth2::AccessToken.new(strategy.client, stored_access_token,
|
|
174
|
+
refresh_token: stored_refresh_token, expires_at: stored_expires_at)
|
|
175
|
+
renewed = token.refresh!
|
|
176
|
+
# Atomically persist renewed.token, renewed.refresh_token, and renewed.expires_at.
|
|
177
|
+
# Preserve the stored refresh token if a token response omits its replacement.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
Use your playground options when constructing that client for development. Carta rotates refresh tokens; serialize refreshes for a given connection and persist the new pair together. If refresh is rejected or expired, ask the user to authorize again. Do not put access/refresh tokens in cookies or browser storage. See the [refresh flow](https://docs.carta.com/api-platform/guides/guides/authorization/using-the-authorization-code-flow/#refresh-token-flow).
|
|
181
|
+
|
|
182
|
+
## Development
|
|
183
|
+
|
|
184
|
+
```sh
|
|
185
|
+
bundle install
|
|
186
|
+
bundle exec rake # Minitest + WebMock; no real network calls
|
|
187
|
+
bundle exec rake build # pkg/omniauth-carta-0.1.0.gem
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
Tests use synthetic [JSON fixtures](test/fixtures), not captured credentials. They exercise the real middleware, token HTTP requests, PKCE/state, CSRF protection, identity mapping, endpoint overrides, errors, and token rotation. CI is configured for Ruby 3.2, 3.3, 3.4, and 4.0. See [implementation plans](plans/README.md) for decisions and verification results.
|
|
191
|
+
|
|
192
|
+
Live playground OAuth and subsequent API access were verified in a consuming Rails application on 2026-09-09. Production sign-in has not been verified. Automated tests use synthetic fixtures; they do not establish that a particular Carta application is provisioned correctly.
|
|
193
|
+
|
|
194
|
+
## License
|
|
195
|
+
|
|
196
|
+
[MIT](LICENSE.txt). This is an independent integration, not an official Carta SDK.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "omniauth-oauth2"
|
|
4
|
+
|
|
5
|
+
module OmniAuth
|
|
6
|
+
module Strategies
|
|
7
|
+
class Carta < OmniAuth::Strategies::OAuth2
|
|
8
|
+
option :name, "carta"
|
|
9
|
+
option :scope, "openid profile email"
|
|
10
|
+
option :pkce, true
|
|
11
|
+
option :userinfo_url, "/o/userinfo/"
|
|
12
|
+
option :client_options,
|
|
13
|
+
site: "https://login.app.carta.com",
|
|
14
|
+
authorize_url: "/o/authorize/",
|
|
15
|
+
token_url: "/o/access_token/",
|
|
16
|
+
auth_scheme: :basic_auth
|
|
17
|
+
|
|
18
|
+
uid { raw_info.fetch("sub") }
|
|
19
|
+
|
|
20
|
+
info do
|
|
21
|
+
{
|
|
22
|
+
name: raw_info["name"],
|
|
23
|
+
first_name: raw_info["given_name"],
|
|
24
|
+
last_name: raw_info["family_name"],
|
|
25
|
+
email: raw_info["email"]
|
|
26
|
+
}.compact
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Extend the inherited OAuth2 credentials without changing token/expiry fields.
|
|
30
|
+
credentials do
|
|
31
|
+
hash = {}
|
|
32
|
+
hash["refresh_token"] = access_token.refresh_token if access_token.refresh_token
|
|
33
|
+
scope = access_token.params["scope"]
|
|
34
|
+
hash["scope"] = scope if scope.is_a?(String)
|
|
35
|
+
hash
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
extra do
|
|
39
|
+
{ raw_info: raw_info }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def raw_info
|
|
43
|
+
@raw_info ||= begin
|
|
44
|
+
response = access_token.get(options.userinfo_url, headers: { "Accept" => "application/json" }).parsed
|
|
45
|
+
unless response.is_a?(Hash) && response["sub"].is_a?(String) && !response["sub"].strip.empty?
|
|
46
|
+
raise CallbackError.new(:invalid_userinfo, "Carta UserInfo must contain a non-empty string sub")
|
|
47
|
+
end
|
|
48
|
+
response
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def callback_url
|
|
53
|
+
options[:callback_url] || (full_host + callback_path)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
protected
|
|
57
|
+
|
|
58
|
+
# omniauth-oauth2 1.9 assumes a stored state exists, including on replay.
|
|
59
|
+
def secure_compare(left, right)
|
|
60
|
+
return false unless left.is_a?(String) && right.is_a?(String)
|
|
61
|
+
|
|
62
|
+
super
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: omniauth-carta
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Avi Flombaum
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: omniauth-oauth2
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.9'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.9'
|
|
26
|
+
description: An OmniAuth OAuth2 strategy for Carta using its UserInfo endpoint, with
|
|
27
|
+
PKCE support.
|
|
28
|
+
executables: []
|
|
29
|
+
extensions: []
|
|
30
|
+
extra_rdoc_files: []
|
|
31
|
+
files:
|
|
32
|
+
- CHANGELOG.md
|
|
33
|
+
- LICENSE.txt
|
|
34
|
+
- README.md
|
|
35
|
+
- lib/omniauth-carta.rb
|
|
36
|
+
- lib/omniauth/carta/version.rb
|
|
37
|
+
- lib/omniauth/strategies/carta.rb
|
|
38
|
+
homepage: https://github.com/aviflombaum/omniauth-carta
|
|
39
|
+
licenses:
|
|
40
|
+
- MIT
|
|
41
|
+
metadata:
|
|
42
|
+
rubygems_mfa_required: 'true'
|
|
43
|
+
source_code_uri: https://github.com/aviflombaum/omniauth-carta
|
|
44
|
+
changelog_uri: https://github.com/aviflombaum/omniauth-carta/blob/main/CHANGELOG.md
|
|
45
|
+
bug_tracker_uri: https://github.com/aviflombaum/omniauth-carta/issues
|
|
46
|
+
rdoc_options: []
|
|
47
|
+
require_paths:
|
|
48
|
+
- lib
|
|
49
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - ">="
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '3.2'
|
|
54
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '0'
|
|
59
|
+
requirements: []
|
|
60
|
+
rubygems_version: 4.0.14
|
|
61
|
+
specification_version: 4
|
|
62
|
+
summary: Carta OAuth2 authentication for OmniAuth
|
|
63
|
+
test_files: []
|