oauth
| Kind | kit |
|---|---|
| Capabilities | net |
| Categories | authentication web |
| Keywords | oauth oauth2 authentication authorization security |
OAuth 2.0 client library for Kit
Files
| File | Description |
|---|---|
.editorconfig | Editor formatting configuration |
.gitignore | Git ignore rules for build artifacts and dependencies |
.tool-versions | asdf tool versions (Zig, Kit) |
LICENSE | MIT license file |
README.md | This file |
examples/client-credentials.kit | Dry-run client credentials example |
examples/github.kit | Dry-run GitHub authorization code example |
kit.toml | Package manifest with metadata, capabilities, and tasks |
src/oauth.kit | OAuth 2.0 client implementation |
tests/oauth.test.kit | Functional tests for OAuth helpers |
tests/types.test.kit | Type and constant behavior tests |
Dependencies
No Kit package dependencies.
This package uses Kit's built-in HTTP and Time modules. The package manifest requests the net capability because token exchange and authenticated request helpers perform HTTP calls.
Installation
kit add gitlab.com/kit-lang/packages/kit-oauth.gitUsage
import Kit.Oauth as OAuth
main = fn =>
config = OAuth.github "client-id" "client-secret" "http://localhost:3000/callback" ["read:user", "user:email"]
state = OAuth.generate-state
auth-url = OAuth.authorize-url config state
println "Open this authorization URL:"
println auth-url
mainAuthorization Code
After the provider redirects back to your callback URL, validate that the returned state matches the state you generated, then exchange the authorization code for tokens:
match OAuth.exchange-code config code
| Ok tokens ->
println "Token type: ${tokens.token-type}"
println "Expires in: ${Int.to-string tokens.expires-in} seconds"
| Err err ->
println "OAuth error: ${err}"Authorization Code with PKCE
Use PKCE for public clients such as desktop apps, mobile apps, and browser-based flows:
verifier = "abcdefghijklmnopqrstuvwxyz0123456789-._~abc"
state = OAuth.generate-state
auth-url = OAuth.authorize-url-pkce config state verifier
match OAuth.exchange-code-pkce config code verifier
| Ok tokens -> println "Access token received"
| Err err -> println "OAuth error: ${err}"The current PKCE helper uses the plain challenge method. It is structured so it can move to S256 once a string SHA256 helper is available.
Client Credentials
Use client credentials for machine-to-machine authentication:
config = OAuth.custom "client-id" "client-secret" "https://auth.example.com/oauth/authorize" "https://auth.example.com/oauth/token" "https://app.example.com/oauth/callback" ["api:read", "api:write"]
match OAuth.client-credentials config
| Ok tokens ->
println "Access token received"
| Err err ->
println "OAuth error: ${err}"Refresh Tokens
match OAuth.refresh-token config refresh-token
| Ok tokens -> println "Refreshed access token"
| Err err -> println "Refresh failed: ${err}"Authenticated Requests
match OAuth.get "https://api.example.com/user" tokens.access-token
| Ok response ->
println "Status: ${Int.to-string response.status}"
println response.body
| Error err ->
println "API error: ${err}"json-body = "{\"name\":\"Kit\"}"
match OAuth.post "https://api.example.com/resources" json-body tokens.access-token
| Ok response -> println "Created: ${Int.to-string response.status}"
| Error err -> println "API error: ${err}"Provider Presets
Built-in provider helpers return an OAuthConfig with provider authorization and token endpoints filled in:
| Helper | Provider |
|---|---|
OAuth.github | GitHub |
OAuth.google | |
OAuth.microsoft | Microsoft Entra ID / Azure AD |
OAuth.discord | Discord |
OAuth.slack | Slack |
OAuth.gitlab | GitLab |
OAuth.custom | Any OAuth 2.0 provider |
Security Notes
- Always validate the callback
statevalue before exchanging an authorization code. - Use HTTPS redirect URIs in production.
- Do not log access tokens, refresh tokens, authorization codes, or client secrets.
- Store refresh tokens in secure storage appropriate for your application.
- Use environment variables or a secret manager for client secrets.
- Treat the checked-in examples as dry-run examples. They are designed to be parity-safe and do not contact live OAuth providers.
Development
Running Examples
Run examples with the interpreter:
kit run examples/github.kit
kit run examples/client-credentials.kitCompile an example to a native binary:
kit build examples/github.kit && ./githubRunning Tests
Run the test suite:
kit testRun the test suite with coverage:
kit test --coverageRunning kit dev
Run the standard development workflow:
kit devThis will:
- Check formatting
- Type-check source files in
src/ - Type-check examples in
examples/ - Run tests in
tests/with coverage
Running Parity
Run interpreter/compiler parity checks for the examples:
kit parity --no-spinner --failures-onlyThe examples use deterministic output and avoid live network calls so parity can compare interpreter and compiled executable output reliably.
Generating Documentation
Generate API documentation from doc comments:
kit docNote: Kit sources with doc comments (##) will generate HTML documents in docs/*.html.
Cleaning Build Artifacts
Remove generated files, caches, parity results, docs, lock files, and native build artifacts:
kit task cleanNote: Defined in kit.toml.
Local Installation
To install this package locally for development:
kit installThis installs the package to ~/.kit/packages/@kit/oauth/, making it available for import as Kit.Oauth in other projects.
License
This package is released under the MIT License - see LICENSE for details.
Exported Functions & Types
authorize-url
OAuthConfig -> String -> String
authorize-url-pkce
OAuthConfig -> String -> String -> String
exchange-code
OAuthConfig -> String -> Result TokenResponse String
exchange-code-pkce
OAuthConfig -> String -> String -> Result TokenResponse String
refresh-token
OAuthConfig -> NonEmptyString -> Result TokenResponse String
client-credentials
OAuthConfig -> Result TokenResponse String
get
NonEmptyString -> NonEmptyString -> Result HttpResponse String
post
NonEmptyString -> String -> NonEmptyString -> Result HttpResponse String
github
NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
google
NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
microsoft
NonEmptyString -> NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
discord
NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
slack
NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
gitlab
NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
custom
NonEmptyString -> NonEmptyString -> NonEmptyString -> NonEmptyString -> NonEmptyString -> List String -> OAuthConfig
generate-state
String
is-expired?
TokenResponse -> Int -> Bool