Guide
This guide assumes that you are either running the Shuttle.Access solution or the docker-compose containers.
Access
Navigate to the front-end and log in using an identity that has Administrator privileges.
- Create these identities:
guide-userwith a password ofguide-passwordAccessGuide.WebApiwith a password ofAccessGuide.WebApi:Password
- If there is only 1 tenant available the identities will be assigned to that tenant; else, assign the identities to the relevant tenant.
- Create a permission called
weather://forecast/view. - Create a role called
Trusted Identityand assign the following permissions:access://sessions/viewaccess://sessions/register
- A role called
Weather Readerand assign it theweather://forecast/viewpermission. - Assign the
Weather Readerrole to theguide-useridentity. - Assign the
Trusted Identityrole to theAccessGuide.WebApiidentity.
Minimal API
Create a new .Net 10 ASP.NET Core Web API project called AccessGuide.WebApi and remember to un-check the Use controllers option and to check the Enable OpenAPI support option.
Add the Scalar.AspNetCore NuGet package and configure it:
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference(options =>
{
options
.WithTitle("Shuttle.Access Guide API")
.WithTheme(ScalarTheme.DeepSpace)
.WithDefaultHttpClient(ScalarTarget.CSharp, ScalarClient.HttpClient);
});
}Also update the launchSettings.json to open the Scalar UI:
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": true,
"launchUrl": "scalar/v1",
"applicationUrl": "http://localhost:<PORT>", <-- use the port assigned
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}If you run the application you should be able to invoke the GET http://localhost:{port}/weatherforecast endpoint to return a list of temperature readings.
Add the following NuGet packages to the project:
- Shuttle.Access.AspNetCore
- Shuttle.Access.RestClient
To enable the Shuttle.Access authorization we need to add the following:
// var builder = WebApplication.CreateBuilder(args); <-- at some point after
builder.Services.AddAccessAuthorization();
// The client application (the Web API in this case) needs to be able to retrieve session
// data from the Shuttle.Access.WebApi. This means that the client application needs
// to be authenticated and register a session, which will have the permissions associated
// with the relevant identity. We'll use the 'AccessGuide.WebApi' credentials
// that we registered above.
builder.Services.AddAccessClient(options =>
{
options.BaseAddress = "http://localhost:5599";
})
.UsePasswordAuthenticationProvider(options =>
{
options.IdentityName = "AccessGuide.WebApi";
options.Password = "AccessGuide.WebApi:Password";
});
// We could also use a Bearer token for an Azure identity, for instance.
//.UseBearerAuthenticationProvider(options =>
//{
// options.GetBearerAuthenticationContextAsync = async (httpRequestMessage, serviceProvider) =>
// {
// var credential = new Azure.Identity.DefaultAzureCredential();
// var scopes = new[] { "https://management.azure.com/.default" };
// return (await credential.GetTokenAsync(new(scopes), CancellationToken.None)).Token;
// };
//})
```c#
// var app = builder.Build(); <-- at some point after
app.UseAccessAuthorization();Then we need to require a permission on the mapping by adding .RequirePermission("weather://forecast/view"):
app.MapGet("/weatherforecast", (HttpContext httpContext) =>
{
/// existing code
})
.RequirePermission("weather://forecast/view") // <-- add this
.WithName("GetWeatherForecast")
.WithOpenApi();If you run the application and invoke the GET http://localhost:{port}/weatherforecast endpoint you should receive a 401 Unauthorized error.
This is because we have not specified the session token.
Use the Shuttle.Access Web API to register a session by invoking the POST /v1/sessions endpoint with the following body:
{
"identityName": "guide-user",
"password": "guide-password"
}You should receive a response with the following structure:
{
"session": {
"dateRegistered": "2026-05-17T08:36:41.0149896+00:00",
"expiryDate": "2026-05-17T16:36:41.0186341+00:00",
"identityDescription": "",
"identityId": "49a37e3d-b44e-456b-9a22-8b01a2ca78b2",
"identityName": "guide-user",
"permissions": [
{
"id": "88de8145-5de9-4a68-9172-dafdda0aa32e",
"name": "weather://forecast/view",
"tenantId": "c3ee3908-716b-48df-abda-33b49e09be97"
}
],
"id": "42ee25a1-24bd-49dc-949b-dd16fa0aee54"
},
"registrationRequested": false,
"result": "Registered",
"token": "1125eee9-fe47-4193-a7e9-8b3a18c05abb",
"tenants": [
{
"id": "c3ee3908-716b-48df-abda-33b49e09be97",
"name": "System",
"status": 1,
"statusName": "Active",
"logoSvg": "",
"logoUrl": ""
}
]
}Copy the token and then add an Authorization header to the AccessGuide.WebApi Scalar /weatherforecast request with a value of Shuttle.Access token=<the-token-value> (without the <>).
When you invoke the GET http://localhost:{port}/weatherforecast endpoint now you should have access.