How To Configure TTK Projects for GCC Development & Testing

Learn how to configure Teams Toolkit projects for GCC environments by removing Azure and Microsoft 365 dependencies, enabling testing and debugging with a local development.

By Last Updated: February 4, 2025 14 minutes read

After some early challenges, Microsoft has significantly improved its developer tooling for creating custom Microsoft Teams applications in recent years. This effort centers on the Teams Toolkit (TTK) label. While many developers think of TTK as just the VS Code extension, it encompasses much more!

In addition to the VS Code extension, the toolkit includes the TTK CLI (aka: teamsapp), a comprehensive suite of utility packages with React hooks for Teams apps, and numerous other tools. Many of these were previously known under the TeamsFx label. You can find these tools, libraries, and their source code in the github.com/OfficeDev/teams-toolkit repository.

However, TTK VS Code extension & CLi hav one significant limitation: they don’t work in non-commercial clouds.

According to the Teams Toolkit for VS Code documentation, it lacks support for GCC, GCC High, DoD, and other government clouds.

Microsoft Teams Toolkit Overview - Not supported in GCC, GCC High, or DoD environments.

Microsoft Teams Toolkit Overview - Not supported in GCC, GCC High, or DoD environments.

Microsoft Teams Toolkit Overview - Not supported in GCC, GCC High, or DoD environments.

It’s not just TTK - the Microsoft Teams Developer Portal is not fully supported in these same environments, further making Teams app development challenging for many customers in the public sector. Microsoft started some work on it, announcing a beta Developer Portal in October 2022, but there hasn’t been much since then.

Recently I’ve been working with some of my coaching clients who are in GCC environments and I’ve seen the pain and frustration this causes, especially since the Microsoft documentation doesn’t address this scenario. In this article, I want to share a process we’ve come up that leverages the flexibility of the TTK to make the process work… albeit with some tedious manual tasks.

The future of TTK for customers in GCC, GCC High, and DoD environments
It’s my understanding that Microsoft does intend to implement TTK in these more secure environments, it’s just not clear if that work is planned or scheduled at the time of writing this article. If things improve over time, I’ll update this article.

Overview - Customizing the Build Process

The biggest challenge you face with the TTK for VS Code (VSC), and the associated CLI, is most operations require you are logged into your Microsoft 365 tenant where you want to test your app. For customers in GCC environments, I find most of them don’t just deploy to to GCC environments but they also develop in them as well. This is required because of the nature of the organization in some cases, while in others have it as a policy to ensure development is as close to production as possible.

To get around these blockers but still get most of the productivity enhancements from the TTK for VSC, we leveraged the flexibility in TTK based projects. There are some manual steps you have to do to each project, but this process works great from my experience.

I’m interested in hearing your experience with this process - please leave a comment at the end of the article!

This process involves making changes to the tasks and launch configurations in TTK-based projects and a few edits to the provision stage in the local development project file. The biggest thing you have to do is remove the dependency by being logged in and connected to a Microsoft 365 tenant.

Once you’ve made these changes, you’ll then manually upload the Teams app package once you’ve signed into Teams in the browser VSC will launch and attach to for debugging.

If your application uses single sign-on (SSO), you’ll need to manually create and configure the Entra ID application used in the SSO configuration.

Let’s get started!

Update the VS Code Tasks

Start by making a few changes to the VSC tasks defined in the ./.vscode/tasks.json file in the project. Ideally I’d like to duplicate and edit two of the default tasks for our use, but the TTK will first ensure you’re logged into your Microsoft 365 account: validating prerequisites & provisioning resources. The point of these steps is to get around the scenario where we can’t login to our Microsoft 365 account, so we can’t use those.

That means you’ll have to manually perform some of the steps in those tasks.

While you can modify the existing tasks, I’m going to create new tasks so the project will still work with regular non-GCC Microsoft 365 tenants.

Create the initial “start” task

Next, duplicate the start task that you’ll normally run if you weren’t in a GCC tenant:

{
  "label": "Start Teams App Locally",
  "dependsOn": [
    "Validate prerequisites",
    "Provision",
    "Deploy",
    "Start application"
  ],
  "dependsOrder": "sequence"
}

In the new copy, do the following:

  1. Remove the Validate prerequisites task from we can’t use from the dependsOn array. This triggers the TTK to force you to login to your Microsoft 365 tenant, which we can’t do in GCC environments.
  2. Rename the label property to Start Teams App Locally (for GCC).

The new task should look like the following:

{
  "label": "Start Teams App Locally (for GCC)",
  "dependsOn": [
    "Provision",
    "Deploy",
    "Start application"
  ],
  "dependsOrder": "sequence"
}

Update the VS Code Launch configurations

While you can run tasks manually in VSCode using the Tasks: Run Task command from the command bar, most prefer to use the selector in the Run and Debug panel to get additional debugging configurations. These relay on the tasks defined in the file you previously modified.

VS Code's Run and Debug panel

VS Code's Run and Debug panel

Create a new config to launch the Teams web client

What we want to do is add a new entry to this list, like you see in the screenshot above: Debug in Teams for GCC (Edge). The easy to way to start is by duplicating an existing entries, so within the configurations array, locate the configuration named Attach to Frontend in Teams (Edge) and duplicate it:

{
  "name": "Attach to Frontend in Teams (Edge)",
  "type": "msedge",
  "request": "launch",
  "url": "https://teams.microsoft.com/l/app/${{local:TEAMS_APP_ID}}?installAppPackage=true&webjoin=true&${account-hint}",
  "presentation": {
    "group": "all",
    "hidden": true
  },
  "cascadeTerminateToConfigurations": [
    "Attach to Local Service"
  ],
  "internalConsoleOptions": "neverOpen"
},

In the new copy, rename it to set the name to Attach to Frontend in Teams for GCC (Edge) and change the url property to only include the base URL for the Teams web client. The default URL will tell Teams to start installing an app when the client loads - we don’t want this because we’ll have to manually upload the Teams app package since the TTK can’t do this for us as it can’t connect to Microsoft 365 GCC tenants:

{
  "name": "Attach to Frontend in Teams for GCC (Edge)",
  "type": "msedge",
  "request": "launch",
  "url": "https://teams.microsoft.com",
  "presentation": {
    "group": "all",
    "hidden": true
  },
  "cascadeTerminateToConfigurations": [
    "Attach to Local Service"
  ],
  "internalConsoleOptions": "neverOpen"
}

Create a new config to attach to the web & local server side processes

Next, we need to add a new compound launch configuration that will do a few things. When triggered, it will:

  1. Run new task Start Teams App Locally (for GCC) we created to bypass the prerequisite validation and provision tasks that require being signed into a Microsoft 365 tenant.
  2. Run the new launch configuration Attach to Frontend in Teams for GCC (Edge) we just created that won’t tell Teams to start installing an app after the browser launches.
  3. Run the existing launch configuration Attach to Local Service that will connect the VSCode debugger to the local Node process’s debugging port (9229).

Within the compounds array, locate and duplicate the existing compound configuration…

{
  "name": "Debug in Teams (Edge)",
  "configurations": [
    "Attach to Frontend in Teams (Edge)",
    "Attach to Local Service"
  ],
  "preLaunchTask": "Start Teams App Locally",
  "presentation": {
    "group": "group 1: Teams",
    "order": 1
  },
  "stopAll": true
},

… and make the following changes:

  • Update the name to Debug in Teams for GCC (Edge)
  • Change the first configuration in the array to use the one you created: Attach to Frontend in Teams for GCC (Edge)
  • Change the preLaunchTask to use the task you created: Start Teams App Locally (for GCC)

Your compound configuration should look like this:

{
  "name": "Debug in Teams for GCC (Edge)",
  "configurations": [
    "Attach to Frontend in Teams for GCC (Edge)",
    "Attach to Local Service"
  ],
  "preLaunchTask": "Start Teams App Locally (for GCC)",
  "presentation": {
    "group": "group 1: Teams",
    "order": 1
  },
    "stopAll": true
},

With the files in the project that control how VS Code works, now you can start making changes to your project’s source code. Unfortunately, that same issue I previously mentioned about the TTK forcing you to be logged into a M365 tenant are going to keep us from using some of the more productive features the TTK VS Code extension and associated TTK CLI have to offer.

Some of the changes I’m going to suggest are good for documentation, but also in case in the future the TTK gives us a way to bypass that M365 login check.

Create a new Entra ID application

By default, the Teams tab project creates an Entra ID application used in a single sign-on (SSO) scenario for your Teams app. This is done using two actions: aadApp/create and aadApp/update.

These two actions creates the Entra ID app using the Microsoft Graph. You may or may not have access to this endpoint - it’s hard to find the documentation if it’s available in the GCC implementation of Microsoft Graph. But, you can delete this action if you’re in a GCC-HIGH or DoD cloud. The action is hard-coded to use the https://graph.microsoft.com endpoint, but the GCC-HIGH & DoD clouds use different endpoints.

So to be safe, I’d manually create the Entra ID application using the Microsoft Entra ID admin center:

  1. Select Manage > App registrations in the left-hand navigation and then select New registration.
  2. On the Register an application page, set the values as follows, and then select Register:
    • Name: Teams GCC Test
    • Supported account types: Accounts in this organizational directory only (Single tenant)

Microsoft Entra ID will then display the details of the new app:

Entra ID application details

Entra ID application details

Create a client secret for the Entra ID app

For an app to authenticate using the OAuth2 client credentials flow with Microsoft Entra ID, it needs both the client ID and a client secret.

  • Select Manage > Certificates and secrets from the left-hand navigation.
  • On the Certificates & Secrets page, select the Client Secrets tab and then select New client secret.
  • Set a description and select an expiration duration, then select Add.
  • When the secret is created, it will be shown one time so make sure you copy this as you’ll need it in a moment.

Create a custom OAuth2 permission

Microsoft Teams needs a special permission (scope) defined on your app to obtain an access token to support SSO. To support this, you need to create the scope on your new app:

  • Select Manage > Expose an API in the left-hand navigation, select the Set link next to the Application AD URI label. This will default the app’s ID to api://<app-id>.
  • Next, select Add a scope to add a new permission for the app. Create a new scope using the following settings and then select Add scope:
    • Scope name: access_as_user
    • Who can consent? Admins and users
    • Admin consent title: Teams can access app’s web APIs
    • Admin consent description: Allows Teams to call the app’s web APIs as the current user.
    • User consent title: Teams can access app’s web APIs and make requests on your behalf
    • User consent description: Enable Teams to call this app’s web APIs with the same rights that you have
    • State: Enabled Next, select Add a scope to add a new permission for the app.

With the new scope get the ID of the new scope:

  • Select Manage > Manifest in the left-hand navigation.
  • Scroll down to the following property: api.oauth2PermissionScopes.id (there should be only one item in this array).
  • Copy the value of the id property as you’ll need it in the next step:

Go back to the app details page for the next step by selecting Overview in the left-hand navigation Keep this page open as you’ll need the values in the next step.

Update the local environment config

The local environment configuration files, ./env/.env.local and ./env/.env.local.user are used to configure the local development process.

Update the Entra ID app’s details

Start by manually updating the following values in the .env.local file for the Entra ID application you just created using the value on the app details page in the Entra ID admin center:

.env.localEntra ID app value
AAD_APP_ACCESS_AS_USER_PERMISSION_IDValue of the id property for the of the access_as_user scope you created in the last step.
TEAMS_APP_TENANT_IDDirectory (tenant) ID
AAD_APP_CLIENT_IDApplication (client) ID
AAD_APP_OBJECT_IDObject ID
AAD_APP_TENANT_IDDirectory (tenant) ID
AAD_APP_OAUTH_AUTHORITYhttps://login.microsoftonline.com/{{Directory (tenant) ID}}
AAD_APP_OAUTH_AUTHORITY_HOSThttps://login.microsoftonline.com

Set the new Teams app’s ID

Finally, create a new GUID and set it to the TEAMS_APP_ID environment variable in the .env.local file.

Update the Entra ID app’s secret details

Set the Entra ID app’s client secret by manually updating the SECRET_AAD_APP_CLIENT_SECRETenvironment variable in the .env.local.user file for the Entra ID application you just created on the environment variable.

Update the local environment provision stage

The existing local project file, ./teamsapp.local.yml, is used to configure the local build. Many of the actions in the provision stage won’t work because you aren’t connected to your Microsoft 365 tenant.

Remove the following actions from the provision stage:

  • aadApp/create
  • teamsApp/create
  • aadApp/update
  • teamsApp/update
  • teamsApp/extendToM365

You should be left with only the following three actions:

  • script
  • teamsApp/validateManifest
  • teamsApp/zipAppPackage

Try it out!

At this point your project should be ready to try the changes out. You’ll still have a few manual steps to perform, but those will need to be done after you’ve run the build process.

Start the debugging process

In VS Code, from the Run and Debug menu item in the left-hand menu, select the launch configuration Debug in Teams for GCC (Edge) and then select the green start arrow:

VSCode's Run and Debug panel

VSCode's Run and Debug panel

After a few moments, you should see the browser launch & load Microsoft Teams (after first prompting you to sign in). Before you sign in, take a moment to update the Entra ID application.

Update the Entra ID application

Previously, you created a basic Entra ID application, but there are additional things you need to set. They couldn’t be set at the time because you needed some values added to your environment file. Some of these were set in the steps above while others were set as part of the provision stage.

Normally, the TTK does this as part of the provision stage using the aadApp/update action, but we can’t rely on it for reasons i previously explained. One thing this action does do that’s very helpful is take a template Entra ID app manifest in the project (./aad.manifest.json) and update values in it from our environment variables. The action then takes this file and updates the existing Entra ID app using this manifest… but we can do that too!

Do the following steps to update the Entra ID application:

  1. Locate and duplicate the ./aad.manifest.json file with the new name of ./aad.manifest.gcc.json. We’re going to make a change to the template but want to keep a copy of the original one in case we ever need it again.

  2. Open the new ./aad.manifest.gcc.json file.

  3. Find all instances of ${{ and replace them with {{.

    We had to replace the ${{ with {{ because the utility we’ll use only understands specific types of template syntaxes. The closest one for us is the Handlebars syntax {{ }}, so we just stripped out the $ prefix before running the command.
  4. Find all instances of permissionIds and replace them with delegatedPermissionIds.

  5. Run the following command in the console from the root of your project:

    npx envsub -s handlebars -f ./env/.env.local ./aad.manifest.gcc.json ./appPackage/build/aad.manifest.local.json
    

This will generate a new template you can use to update your Entra ID application. Open the ./appPackage/build/aad.manifest.local.json.

Using the Microsoft Entra ID admin center:

  1. Select the application you previously created

  2. Select Manage > Manifest in the left-hand navigation.

  3. Locate the property requestedAccessTokenVersion and set it to 2.

  4. Locate the property identifierUris and replace it with the value of the same property in the aad.manifest.local.json file.

  5. Locate the array preAuthorizedApplications and replace it with the value of the same property in the aad.manifest.local.json file.

  6. Locate the array web.redirectUriSettings & update it using the following steps:

    1. In the aad.manifest.local.json file, locate the replyUrlsWithType property.

    2. Get the value of the url where the type=Web.

    3. Add a the following object to the manifest’s web.redirectUriSettings:

      {
        "uri": "<<< value of uri copied in the step above >>>",
        "index": null
      }
      
  7. Locate the array spa.redirectUris and add the values in the property replyUrlsWithType.url aad.manifest.local.json file where the type= Spa.

At this point, your Entra ID app has been configured.

Sign-in to Microsoft Teams and install your app!

Now, you can finally install your Teams app!

Go back to the browser that VS Code launched and sign-in to Microsoft Teams.

At this point, provided have permissions to side load your application, you can upload the app directly to a team, channel, or selecting the Apps > Manage your Apps page in the Teams client where you can choose the option to Upload an app.

In this case, select the app package generated in your project: ./appPackage/build/appPackage.local.zip.

Conclusion

Yes, this process is quite tedious. It would be a lot easier if there was an option, maybe as an environment variable setting that would configure the TTK to skip steps that require you to be signed into Microsoft 365 tenants. Then, actions could be configured to skip those steps.

Or… Microsoft could get the necessary hooks for the TTK VS Code extension and CLI, like the Teams Developer Portal, deployed to GCC tenants.

Did you try these steps? Let me know if they worked (or not) for you by leaving a comment below!

Branded horizontal divider.