Quick start
-
Accept the invitation. Tenon IT sends your organization’s first Administrator a link to
https://admin.glow-kin.com/console/invite/…. Open it, choose a password, and set up your own two-step sign-in. The link works once, for 72 hours. -
Create an application and its API key. In the console:
- go to Applications and Add an application, e.g. “Customer portal”;
- Create an API key and copy it: it starts with
tnk_and is shown once.
Keep it in your server’s secret settings, never in a browser or a mobile app. Each application gets its own key, and you can create a new one and revoke the old one at any time.
-
Install the SDK for your server’s language (downloads), and create one client with the address and the key:
TenonAuthClient tenonAuth = TenonAuthClient.builder().baseUrl("https://api.glow-kin.com").apiKey(System.getenv("TENON_AUTH_API_KEY")).build();import { TenonAuthClient } from '@tenon-auth/sdk';const tenonAuth = new TenonAuthClient({ baseUrl: 'https://api.glow-kin.com', apiKey: process.env.TENON_AUTH_API_KEY! });from tenon_auth import TenonAuthClienttenon_auth = TenonAuthClient("https://api.glow-kin.com", os.environ["TENON_AUTH_API_KEY"])var tenonAuth = new TenonAuthClient(new TenonAuthClientOptions{BaseUrl = "https://api.glow-kin.com",ApiKey = builder.Configuration["TenonAuth:ApiKey"],}); -
Let users set up a method on their settings page: authenticator codes, sign-in approval, or email codes if your Administrator allows them. Then show them recovery codes once. See Setting up a method.
-
Add the second step to your sign-in, right after the password is checked:
SecondStep step = tenonAuth.beginSecondStep(account.id(), new SignInContext(clientIp, userAgent));session.setAttribute("secondStep", step);// CODE_ENTRY: show the code page. PUSH_WAIT: show step.number() and wait.// TRUSTED or NO_METHOD: sign in (NO_METHOD: or ask them to set one up first).// The code page's form:if (tenonAuth.completeWithCode(step, code).approved()) signIn(account);const step = await tenonAuth.beginSecondStep(account.id, { context: { ipAddress: req.ip, userAgent: req.get('user-agent') } });req.session.secondStep = step;// CODE_ENTRY: show the code page. PUSH_WAIT: show step.number and wait.// The code page's form:if ((await tenonAuth.completeWithCode(req.session.secondStep, req.body.code)).approved) signIn(account);step = tenon_auth.begin_second_step(str(account.id), SignInContext(client_ip, user_agent))session["second_step"] = step.to_dict()# CODE_ENTRY: show the code page. PUSH_WAIT: show step.number and wait.# The code page's form:if tenon_auth.complete_with_code(SecondStep.from_dict(session["second_step"]), form["code"]).approved:sign_in(account)var step = await tenonAuth.BeginSecondStepAsync(account.Id.ToString(), new SignInContext(ip, userAgent));HttpContext.Session.SetString("SecondStep", JsonSerializer.Serialize(step));// CodeEntry: show the code page. PushWait: show step.Number and wait.// The code page's form:if ((await tenonAuth.CompleteWithCodeAsync(step, form.Code)).Approved) SignIn(account);
Then read Signing in for the pages to build, and When Tenon-Auth can’t be reached. Every application must fail closed.