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

# Build on Your Own Workspace

> Start building with your nsc login and your own workspace, before your partner account is set up.

You don't need a partner account to start building.
When you log in with `nsc login`, the SDKs can use that login to act inside your own workspace, the same way a [tenant token](/docs/platform/authentication/tenant-tokens) acts inside a customer's tenant.

That makes your workspace a good place to develop the parts of your platform that run inside a tenant, such as creating [instances](/docs/platform/instances/quickstart) or managing [revokable tokens](/docs/platform/authentication/revokable-tokens).
When your partner account is ready, the same code runs in your customers' tenants. Only the source of the token changes.

<Warning>
  Use your `nsc login` for local development only. In production, your platform issues a [tenant token](/docs/platform/authentication/tenant-tokens) for each customer's tenant.
</Warning>

## Create a client from your login

<Steps titleSize="h3">
  <Step title="Log in">
    [Install the `nsc` CLI](/docs/reference/cli/installation) and log in.
    The browser asks you to pick a workspace. The SDKs act inside the workspace you pick.

    ```bash theme={null}
    nsc login
    ```
  </Step>

  <Step title="Create the client">
    `loadDefaults()` loads your login, and the client authenticates with it.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { createIAMClient } from "@namespacelabs/sdk/api/iam";
      import { loadDefaults } from "@namespacelabs/sdk/auth";

      const tenantClient = createIAMClient({
        tokenSource: await loadDefaults(),
      });
      ```

      ```go Go theme={null}
      import (
      	"log"

      	"namespacelabs.dev/integrations/api/iam"
      	"namespacelabs.dev/integrations/auth"
      )

      tokens, err := auth.LoadDefaults()
      if err != nil {
      	log.Fatal(err)
      }

      tenantClient, err := iam.NewClient(ctx, tokens)
      if err != nil {
      	log.Fatal(err)
      }
      defer tenantClient.Close()
      ```
    </CodeGroup>

    The SDK issues short-lived tokens from your login session and renews them automatically, so the client keeps working for as long as you stay logged in.
  </Step>

  <Step title="Test the client">
    Reading your workspace's policies is a read-only call, which makes it a safe first request.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      const { policies } = await tenantClient.tenants.describePolicies({});

      console.log(`Authenticated. Policies found: ${policies.length}.`);
      ```

      ```go Go theme={null}
      import iamv1beta "namespacelabs.dev/integrations/proto/namespace/cloud/iam/v1beta"

      resp, err := tenantClient.Tenants.DescribePolicies(ctx, &iamv1beta.DescribePoliciesRequest{})
      if err != nil {
      	log.Fatal(err)
      }

      fmt.Printf("Authenticated. Policies found: %d.\n", len(resp.Policies))
      ```
    </CodeGroup>
  </Step>
</Steps>

<Note>
  The client acts inside the workspace you picked at login, not a customer's tenant. Anything you create belongs to that workspace and counts toward its usage.
</Note>

If `NSC_TOKEN_FILE` is set, `loadDefaults()` uses that token file instead of your login. Unset it to go back to your login.

## Use a development token instead

`loadDefaults()` works when your code runs on the machine where you logged in.
To run it somewhere else, such as a script on another machine or a container, use a development token instead.
It acts in the same workspace as your login.

<Steps titleSize="h3">
  <Step title="Generate a development token">
    Run this on the machine where you ran `nsc login`, because it uses your login.

    <CodeGroup>
      ```bash nsc CLI theme={null}
      nsc auth generate-dev-token
      ```
    </CodeGroup>

    The token lasts about an hour and is not renewed, so generate a new one when it expires.
  </Step>

  <Step title="Create the client from the token">
    Pass the token to the client where your code runs.
    This example reads it from a `NAMESPACE_TOKEN` environment variable.

    <CodeGroup>
      ```typescript TypeScript theme={null}
      import { createIAMClient } from "@namespacelabs/sdk/api/iam";
      import { fromBearerToken } from "@namespacelabs/sdk/auth";

      const tenantClient = createIAMClient({
        tokenSource: fromBearerToken(process.env.NAMESPACE_TOKEN!),
      });
      ```

      ```go Go theme={null}
      tenantClient, err := iam.NewClient(ctx, bearerTokenSource(os.Getenv("NAMESPACE_TOKEN")))
      if err != nil {
      	log.Fatal(err)
      }
      defer tenantClient.Close()
      ```
    </CodeGroup>
  </Step>
</Steps>

Your login is the better choice for code that runs on your own machine, because the SDK renews its tokens for you.

## What you can build this way

Your login works with every Namespace client, not just IAM, and for everything a tenant token can do. You can build and test:

* Running [instances](/docs/platform/instances/quickstart), builds, and other workloads.
* Using [storage](/docs/platform/storage), such as cache volumes, the container registry, and secrets.
* Reading [policies](/docs/platform/tenants/policies#read-a-tenants-policies).
* Creating, listing, and revoking [revokable tokens](/docs/platform/authentication/revokable-tokens).

Pass the same token source to any client. For example, a Compute client that lists the instances in your workspace:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { createComputeClient } from "@namespacelabs/sdk/api/compute";
  import { loadDefaults } from "@namespacelabs/sdk/auth";

  const compute = createComputeClient({ tokenSource: await loadDefaults() });

  const { instances } = await compute.compute.listInstances({});
  ```

  ```go Go theme={null}
  import (
  	"namespacelabs.dev/integrations/api/compute"
  	"namespacelabs.dev/integrations/auth"
  	computepb "namespacelabs.dev/integrations/proto/namespace/cloud/compute/v1beta"
  )

  tokens, err := auth.LoadDefaults()
  if err != nil {
  	log.Fatal(err)
  }

  computeClient, err := compute.NewClient(ctx, tokens)
  if err != nil {
  	log.Fatal(err)
  }
  defer computeClient.Close()

  resp, err := computeClient.Compute.ListInstances(ctx, &computepb.ListInstancesRequest{})
  ```
</CodeGroup>

Managing tenants needs [partner credentials](/docs/platform/authentication/partner-credentials), so your login can't create, list, update, or delete tenants, set their policies, or issue tenant tokens.

## Move to production

In production, your service acts for a customer with a tenant token instead of your login.
Your platform [issues the token for the customer's tenant](/docs/platform/authentication/tenant-tokens#issue-a-tenant-token) with its partner credentials. Replace `loadDefaults()` with that token:

<CodeGroup>
  ```typescript TypeScript theme={null}
  import { fromBearerToken } from "@namespacelabs/sdk/auth";

  const tenantClient = createIAMClient({
    tokenSource: fromBearerToken(bearerToken),
  });
  ```

  ```go Go theme={null}
  tenantClient, err := iam.NewClient(ctx, bearerTokenSource(bearerToken))
  ```
</CodeGroup>

The rest of your code stays the same.

## Next steps

<Columns cols={2}>
  <Card title="Instances quickstart" icon="play" href="/docs/platform/instances/quickstart">
    Run your first instance in your workspace.
  </Card>

  <Card title="Partner credentials" icon="key-round" href="/docs/platform/authentication/partner-credentials">
    Set up partner credentials to manage tenants.
  </Card>
</Columns>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.