An open API service indexing awesome lists of open source software.

https://github.com/icoretech/omniauth-slack2

🔌 OmniAuth strategy for Slack OpenID Connect authentication
https://github.com/icoretech/omniauth-slack2

authentication gem identity oauth-provider oauth2 omniauth omniauth-strategy openid-connect rails ruby slack

Last synced: 3 months ago
JSON representation

🔌 OmniAuth strategy for Slack OpenID Connect authentication

Awesome Lists containing this project

README

          

# OmniAuth Slack Strategy

[![Test](https://github.com/icoretech/omniauth-slack2/actions/workflows/test.yml/badge.svg?branch=main)](https://github.com/icoretech/omniauth-slack2/actions/workflows/test.yml?query=branch%3Amain)
[![Gem Version](https://badge.fury.io/rb/omniauth-slack2.svg)](https://badge.fury.io/rb/omniauth-slack2)

`omniauth-slack2` provides a Slack OpenID Connect strategy for OmniAuth.

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'omniauth-slack2'
```

Then run:

```bash
bundle install
```

## Usage

Configure OmniAuth in your Rack/Rails app:

```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :slack2,
ENV.fetch('SLACK_CLIENT_ID'),
ENV.fetch('SLACK_CLIENT_SECRET')
end
```

Compatibility alias is available, so you can keep existing callback paths using `slack`:

```ruby
Rails.application.config.middleware.use OmniAuth::Builder do
provider :slack,
ENV.fetch('SLACK_CLIENT_ID'),
ENV.fetch('SLACK_CLIENT_SECRET')
end
```

If you support both names during a migration, register both callback paths in Slack:

- `https://your-app.example.com/auth/slack2/callback`
- `https://your-app.example.com/auth/slack/callback`

## Provider App Setup

- Slack API Dashboard:
- Enable **Sign in with Slack** under OAuth & Permissions
- Register the callback URL that matches your provider name:
- `slack2`: `https://your-app.example.com/auth/slack2/callback`
- `slack`: `https://your-app.example.com/auth/slack/callback`
- If your Slack app enforces PKCE, this strategy sends `code_challenge` / `code_verifier`
with `S256` by default
- Required scopes: `openid`, `email`, `profile`

## Options

Supported request options include:

- `scope` (default: `openid email profile`)
- `nonce` (auto-generated by default)
- `team` (pre-select a Slack workspace)
- `pkce` (default: `true` — sends `code_challenge` / `code_verifier` using `S256`)
- `skip_jwt` (default: `false` — set to `true` to skip id_token RS256 verification)

## Troubleshooting

- If Slack rejects a local callback while your app is enforcing PKCE, prefer a real
HTTPS hostname over `localhost` for interactive testing
- The same callback/PKCE rules apply to the compat `slack` alias, not just `slack2`

## Auth Hash

Example payload from `request.env['omniauth.auth']` (realistic shape, anonymized):

```json
{
"uid": "U0R7MFMJM",
"info": {
"name": "Sample User",
"email": "sample@example.test",
"unverified_email": "sample@example.test",
"email_verified": true,
"first_name": "Sample",
"last_name": "User",
"image": "https://secure.gravatar.com/avatar/example.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fexample.png",
"locale": "en-US"
},
"credentials": {
"token": "xoxp-...",
"refresh_token": "xoxe-1-...",
"expires_at": 1772691847,
"expires": true,
"scope": "openid email profile"
},
"extra": {
"raw_info": {
"ok": true,
"sub": "U0R7MFMJM",
"https://slack.com/user_id": "U0R7MFMJM",
"https://slack.com/team_id": "T0123ABC456",
"email": "sample@example.test",
"email_verified": true,
"date_email_verified": 1775000482,
"name": "Sample User",
"picture": "https://secure.gravatar.com/avatar/example.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fexample.png",
"given_name": "Sample",
"family_name": "User",
"locale": "en-US",
"https://slack.com/team_name": "Sample Workspace",
"https://slack.com/team_domain": "sampleworkspace",
"https://slack.com/user_image_512": "https://secure.gravatar.com/avatar/example.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fexample.png",
"https://slack.com/team_image_230": "https://avatars.slack-edge.com/example-team_132.jpg",
"https://slack.com/team_image_default": false
},
"id_token": "eyJhbGciOiJSUzI1NiIs...",
"id_info": {
"iss": "https://slack.com",
"sub": "U0R7MFMJM",
"aud": "your-client-id",
"exp": 1775009314,
"iat": 1775009014,
"auth_time": 1775009014,
"nonce": "auto-generated-nonce",
"https://slack.com/team_id": "T0123ABC456",
"https://slack.com/user_id": "U0R7MFMJM",
"email": "sample@example.test",
"email_verified": true,
"date_email_verified": 1775000482,
"locale": "en-US",
"name": "Sample User",
"picture": "https://secure.gravatar.com/avatar/example.jpg?s=512&d=https%3A%2F%2Fa.slack-edge.com%2Fexample.png",
"given_name": "Sample",
"family_name": "User",
"https://slack.com/team_name": "Sample Workspace",
"https://slack.com/team_domain": "sampleworkspace",
"https://slack.com/team_image_230": "https://avatars.slack-edge.com/example-team_132.jpg",
"https://slack.com/team_image_default": false
},
"team_id": "T0123ABC456",
"team_name": "Sample Workspace",
"team_domain": "sampleworkspace"
}
}
```

## Development

```bash
bundle install
bundle exec standardrb --fix
bundle exec rake
```

Run Rails integration tests with an explicit Rails version:

```bash
RAILS_VERSION='~> 8.1.0' bundle install
RAILS_VERSION='~> 8.1.0' bundle exec rake test_rails_integration
```

## Compatibility

- Ruby: `>= 3.2` (tested on `3.2`, `3.3`, `3.4`, `4.0`)
- `omniauth-oauth2`: `>= 1.8`, `< 2.0`
- Rails integration lanes: `~> 7.1.0`, `~> 7.2.0`, `~> 8.0.0`, `~> 8.1.0`

## Endpoints

This gem uses Slack OpenID Connect endpoints:

- `https://slack.com/openid/connect/authorize`
- `https://slack.com/api/openid.connect.token`
- `https://slack.com/api/openid.connect.userInfo`
- `https://slack.com/openid/connect/keys` (JWKS for id_token verification)

## Test Structure

- `test/omniauth_slack2_test.rb`: strategy/unit behavior
- `test/rails_integration_test.rb`: full Rack/Rails request+callback flow
- `test/test_helper.rb`: shared test bootstrap

## Release

Tag releases as `vX.Y.Z`; GitHub Actions publishes the gem to RubyGems.

## License

MIT