> ## Documentation Index
> Fetch the complete documentation index at: https://s2.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Access Tokens

> Manage access tokens with S2 SDKs: list existing tokens, issue scoped tokens, and revoke tokens.

Access tokens control what a client can do. Each token has a scope that restricts which basins and streams it can access, and what operations it can perform.

See the [access tokens guide](/concepts/access-tokens) for the full specification, including operation groups, granular permissions, and auto-prefixing for multi-tenant setups.

<Tabs>
  <Tab title="TypeScript">
    ```typescript theme={null}
    // List tokens (returns metadata, not the secret)
    const tokens = await client.accessTokens.list();

    // Issue a token scoped to streams under "users/1234/"
    const { accessToken: issuedToken } = await client.accessTokens.issue({
    	id: "user-1234-rw-token",
    	scope: {
    		basins: { prefix: "" }, // all basins
    		streams: { prefix: "users/1234/" },
    		opGroups: { stream: { read: true, write: true } },
    	},
    	expiresAt: new Date("2027-01-01"),
    });

    // Revoke a token
    await client.accessTokens.revoke({ id: "user-1234-rw-token" });
    ```
  </Tab>

  <Tab title="Python">
    ```python theme={null}
    # List tokens (returns metadata, not the secret)
    tokens = await client.list_access_tokens()

    # Issue a token scoped to streams under "users/1234/"
    issued_token = await client.issue_access_token(
        "user-1234-rw-token",
        scope=AccessTokenScope(
            basins=PrefixMatch(""),  # all basins
            streams=PrefixMatch("users/1234/"),
            op_groups=OperationGroupPermissions(
                stream=Permission.READ_WRITE,
            ),
        ),
        expires_at=datetime(2027, 1, 1, tzinfo=timezone.utc),
    )

    # Revoke a token
    await client.revoke_access_token("user-1234-rw-token")
    ```
  </Tab>

  <Tab title="Go">
    ```go theme={null}
    // List tokens (returns metadata, not the secret)
    tokens, _ := client.AccessTokens.List(ctx, nil)

    // Issue a token scoped to streams under "users/1234/"
    expires := time.Date(2027, 1, 1, 0, 0, 0, 0, time.UTC)
    result, _ := client.AccessTokens.Issue(ctx, s2.IssueAccessTokenArgs{
    	ID: "user-1234-rw-token",
    	Scope: s2.AccessTokenScope{
    		Basins:  &s2.ResourceSet{Prefix: s2.String("")}, // all basins
    		Streams: &s2.ResourceSet{Prefix: s2.String("users/1234/")},
    		OpGroups: &s2.PermittedOperationGroups{
    			Stream: &s2.ReadWritePermissions{Read: true, Write: true},
    		},
    	},
    	ExpiresAt: &expires,
    })

    // Revoke a token
    client.AccessTokens.Revoke(ctx, s2.RevokeAccessTokenArgs{ID: "user-1234-rw-token"})
    ```
  </Tab>

  <Tab title="Rust">
    ```rust theme={null}
    // List tokens (returns metadata, not the secret)
    let tokens = client.list_access_tokens(Default::default()).await?;

    // Issue a token scoped to streams under "users/1234/"
    let result = client
        .issue_access_token(
            IssueAccessTokenInput::new(
                "user-1234-rw-token".parse()?,
                AccessTokenScopeInput::from_op_group_perms(
                    OperationGroupPermissions::new()
                        .with_stream(ReadWritePermissions::read_write()),
                )
                .with_basins(BasinMatcher::Prefix("".parse()?)) // all basins
                .with_streams(StreamMatcher::Prefix("users/1234/".parse()?)),
            )
            .with_expires_at("2027-01-01T00:00:00Z".parse()?),
        )
        .await?;

    // Revoke a token
    client
        .revoke_access_token("user-1234-rw-token".parse()?)
        .await?;
    ```
  </Tab>
</Tabs>
