openapi: 3.2.0 info: title: NUS Identity Provider API (vafs.nus.edu.sg) Authorization API version: '2026-08-19' description: "The National University of Singapore operates its own federated identity service at\n`vafs.nus.edu.sg` (\"NUS VAFS\" — the university's Active Directory Federation Services\ndeployment). It is the one substantial machine-readable, institution-operated API surface\nNUS publishes to the open internet, and it is the front door to essentially every gated\nNUS system.\n\nThe host is unambiguously NUS's own engineering, not a vendor's:\n\n * `vafs.nus.edu.sg` resolves inside NUS's own address space (137.132.21.18).\n * Its TLS certificate is an Extended Validation certificate issued to\n `jurisdictionC=SG, businessCategory=Private Organization, serialNumber=200604346E,\n O=National University of Singapore, CN=vafs.nus.edu.sg` — NUS is the validated\n organization, not a hosting provider.\n * The SAML entityID it asserts is `https://vafs.nus.edu.sg/adfs/services/trust`.\n\nThis document is DERIVED — every path, parameter, scope and response below was read out of\nthe institution's own live OpenID Connect discovery document at\n`https://vafs.nus.edu.sg/adfs/.well-known/openid-configuration` and its JWKS at\n`https://vafs.nus.edu.sg/adfs/discovery/keys`, both fetched 2026-08-19. NUS does not itself\npublish an OpenAPI description; nothing here is invented, but the OpenAPI packaging is\nAPI Evangelist's, not the university's.\n\nThe service speaks OpenID Connect 1.0 / OAuth 2.0, SAML 2.0, WS-Federation and WS-Trust\nfrom the same endpoint family. The SAML half is described in\n`identity-federation/nus-identity-federation.yml`.\n" contact: name: NUS Information Technology url: https://nusit.nus.edu.sg/ termsOfService: https://nus.edu.sg/ormc/personal-data-protection/nus-privacy-notice x-operator: institution x-operator-evidence: - TLS certificate subject O=National University of Singapore (DigiCert EV RSA CA G2) - A record 137.132.21.18 within NUS-assigned address space - SAML entityID https://vafs.nus.edu.sg/adfs/services/trust x-method: derived x-source: https://vafs.nus.edu.sg/adfs/.well-known/openid-configuration x-generated: '2026-08-19' servers: - url: https://vafs.nus.edu.sg description: NUS federated identity service (production) tags: - name: Authorization description: OAuth 2.0 / OpenID Connect authorization and token issuance. paths: /adfs/oauth2/authorize/: get: tags: - Authorization operationId: authorize summary: OAuth 2.0 / OIDC authorization endpoint description: Begins an interactive authorization request. The user authenticates against NUS credentials (and MFA where the relying party requires it) and is redirected back to the client with a code, an id_token, or both, per `response_type`. security: [] parameters: - name: client_id in: query required: true description: Identifier of the relying party registered with NUS IT. schema: type: string - name: response_type in: query required: true description: One of the provider's advertised response types. schema: type: string enum: - code - id_token - code id_token - id_token token - code token - code id_token token - name: redirect_uri in: query required: true schema: type: string format: uri - name: scope in: query required: true description: Space-delimited subset of the provider's advertised scopes. schema: type: string example: openid profile email - name: response_mode in: query required: false schema: type: string enum: - query - fragment - form_post - name: state in: query required: false schema: type: string - name: nonce in: query required: false schema: type: string - name: resource in: query required: false description: ADFS relying-party resource identifier. schema: type: string responses: '302': description: Redirect back to `redirect_uri` carrying the authorization response. headers: Location: schema: type: string format: uri '400': description: Invalid or unregistered authorization request. /adfs/oauth2/token/: post: tags: - Authorization operationId: token summary: OAuth 2.0 token endpoint description: Exchanges a grant for tokens. The provider advertises the authorization_code, refresh_token, client_credentials, jwt-bearer, implicit, password, device_code and srv_challenge grant types. security: - clientSecretBasic: [] - clientSecretPost: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: - grant_type properties: grant_type: type: string enum: - authorization_code - refresh_token - client_credentials - urn:ietf:params:oauth:grant-type:jwt-bearer - implicit - password - srv_challenge - urn:ietf:params:oauth:grant-type:device_code - device_code code: type: string refresh_token: type: string redirect_uri: type: string format: uri client_id: type: string client_secret: type: string client_assertion_type: type: string client_assertion: type: string scope: type: string responses: '200': description: Token response. content: application/json: schema: $ref: '#/components/schemas/TokenResponse' '400': description: OAuth 2.0 error response. content: application/json: schema: $ref: '#/components/schemas/OAuthError' /adfs/oauth2/devicecode: post: tags: - Authorization operationId: deviceAuthorization summary: Device authorization endpoint description: RFC 8628 device authorization grant, for input-constrained clients on the NUS network. security: [] requestBody: required: true content: application/x-www-form-urlencoded: schema: type: object required: - client_id properties: client_id: type: string scope: type: string responses: '200': description: Device code, user code and verification URI. content: application/json: schema: $ref: '#/components/schemas/DeviceCodeResponse' '400': description: OAuth 2.0 error response. content: application/json: schema: $ref: '#/components/schemas/OAuthError' components: schemas: DeviceCodeResponse: type: object required: - device_code - user_code - verification_uri properties: device_code: type: string user_code: type: string verification_uri: type: string format: uri expires_in: type: integer interval: type: integer TokenResponse: type: object required: - access_token - token_type properties: access_token: type: string token_type: type: string example: bearer expires_in: type: integer example: 3600 refresh_token: type: string refresh_token_expires_in: type: integer id_token: type: string description: JWT signed with RS256. scope: type: string OAuthError: type: object required: - error properties: error: type: string example: invalid_grant error_description: type: string securitySchemes: bearerAuth: type: http scheme: bearer bearerFormat: JWT clientSecretBasic: type: http scheme: basic description: client_secret_basic client authentication. clientSecretPost: type: apiKey in: header name: Authorization description: Placeholder for client_secret_post; the provider also advertises private_key_jwt and windows_client_authentication. oidc: type: openIdConnect openIdConnectUrl: https://vafs.nus.edu.sg/adfs/.well-known/openid-configuration