Jakarta Security Interview Questions and Answers

Master Jakarta Security with production-ready interview questions covering authentication, authorization, IdentityStore, HttpAuthenticationMechanism, SecurityContext, role-based access control, JWT integration, REST API security, password handling, and senior-level best practices.


Jakarta Security Interview Questions and Answers

Introduction

Jakarta Security provides a standard security programming model for Jakarta EE applications.

It helps applications implement common security requirements such as:

  • User authentication
  • Role-based authorization
  • Identity validation
  • Credential validation
  • Security-context access
  • Form-based login
  • Basic authentication
  • Custom authentication mechanisms
  • Integration with REST resources
  • Declarative access control

Jakarta Security works together with other Jakarta EE technologies, including:

  • Jakarta REST
  • Jakarta Servlet
  • Jakarta CDI
  • Jakarta Persistence
  • Jakarta Bean Validation
  • Jakarta Transactions

A production-ready security design must consider much more than checking a username and password.

It must also address:

  • Password hashing
  • Credential storage
  • Session security
  • Token validation
  • Role mapping
  • Resource ownership
  • Multi-factor authentication
  • Secure cookies
  • CSRF protection
  • CORS
  • Rate limiting
  • Audit logging
  • Error handling
  • Secret management
  • Token expiration
  • Revocation
  • Least privilege
  • Defense in depth

Authentication answers:

Who is the caller?

Authorization answers:

What is the caller allowed to do?

A secure enterprise application must implement both correctly.

This guide covers the 15 most frequently asked Jakarta Security interview questions with code examples, Mermaid diagrams, production scenarios, common mistakes, and senior-level recommendations.


Q1. What is Jakarta Security?

Answer

Jakarta Security is the Jakarta EE specification that standardizes application-level authentication and identity-store integration.

It provides APIs and annotations for:

  • Authentication mechanisms
  • Credential validation
  • Identity stores
  • Security context access
  • Role checks
  • Login status handling
  • Container integration

Jakarta Security allows applications to define security behavior using standard Jakarta EE APIs rather than relying entirely on application-server-specific configuration.

Main Components

  • HttpAuthenticationMechanism
  • IdentityStore
  • IdentityStoreHandler
  • SecurityContext
  • Credential
  • AuthenticationStatus
  • AuthenticationParameters
  • Security annotations

High-Level Architecture

flowchart TD
    A[Client Request] --> B[Jakarta EE Container]
    B --> C[HTTP Authentication Mechanism]
    C --> D[Identity Store Handler]
    D --> E[Identity Store]
    E --> F[User Credentials and Groups]
    F --> G[Authenticated Principal]
    G --> H[Security Context]
    H --> I[Authorization Check]
    I --> J[Protected Resource]

Why Interviewers Ask This

Interviewers want to know whether you understand Jakarta Security as a standard container-integrated security model rather than a standalone authentication server.

Production Example

A customer portal may use Jakarta Security to authenticate users against a database-backed identity store and then protect REST endpoints with role checks.

Common Mistake

Describing Jakarta Security as a complete OAuth 2.0 or OpenID Connect provider.

Senior Follow-up

Jakarta Security handles application authentication and identity validation, but external identity federation is commonly delegated to a dedicated identity provider.


Q2. What is the difference between authentication and authorization?

Answer

Authentication verifies the identity of the caller.

Authorization determines whether the authenticated caller has permission to perform an action.

Authentication Examples

  • Username and password
  • Client certificate
  • One-time password
  • JWT token
  • Session cookie
  • API key
  • External identity-provider login

Authorization Examples

  • Only administrators can delete users.
  • Customers can access only their own accounts.
  • Claims adjusters can approve claims below a limit.
  • Managers can view department reports.
  • Service accounts can call specific APIs.

Security Flow

flowchart TD
    A[Incoming Request] --> B{Authenticated?}
    B -->|No| C[Authenticate Caller]
    C --> D{Authentication Successful?}
    D -->|No| E[Return 401 Unauthorized]
    D -->|Yes| F[Create Security Identity]
    B -->|Yes| F
    F --> G{Authorized for Resource?}
    G -->|No| H[Return 403 Forbidden]
    G -->|Yes| I[Execute Protected Operation]

Comparison

Authentication Authorization
Confirms identity Confirms permission
Happens first Happens after authentication
Uses credentials Uses roles, permissions, ownership, or policy
Failure commonly returns 401 Failure commonly returns 403
Example: login Example: access admin endpoint

Example

if (!securityContext.getCallerPrincipal()
        .getName()
        .equals(accountOwner)) {

    throw new ForbiddenException();
}

Common Mistake

Using authentication as proof that a caller may access every authenticated resource.

Senior Follow-up

Role checks are often insufficient by themselves. Fine-grained resource ownership and business policy checks may also be required.


Q3. What is an IdentityStore?

Answer

An IdentityStore validates caller credentials and returns identity information such as groups or roles.

It can validate credentials against:

  • A relational database
  • LDAP
  • An external directory
  • A custom user store
  • An enterprise identity system

Basic Interface Role

An identity store typically performs one or both operations:

  • Credential validation
  • Group retrieval

Database Identity Store Concept

flowchart LR
    A[Authentication Mechanism] --> B[IdentityStoreHandler]
    B --> C[Database IdentityStore]
    C --> D[User Table]
    C --> E[Role or Group Table]

Custom Identity Store Example

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.security.enterprise.credential.UsernamePasswordCredential;
import jakarta.security.enterprise.identitystore.CredentialValidationResult;
import jakarta.security.enterprise.identitystore.IdentityStore;

import java.util.Set;

@ApplicationScoped
public class ApplicationIdentityStore
    implements IdentityStore {

    private final UserRepository userRepository;
    private final PasswordService passwordService;

    public ApplicationIdentityStore(
        UserRepository userRepository,
        PasswordService passwordService
    ) {
        this.userRepository = userRepository;
        this.passwordService = passwordService;
    }

    @Override
    public CredentialValidationResult validate(
        UsernamePasswordCredential credential
    ) {

        return userRepository
            .findByUsername(
                credential.getCaller()
            )
            .filter(UserAccount::isActive)
            .filter(
                user -> passwordService.matches(
                    credential.getPasswordAsString(),
                    user.getPasswordHash()
                )
            )
            .map(
                user ->
                    new CredentialValidationResult(
                        user.getUsername(),
                        user.getRoles()
                    )
            )
            .orElse(
                CredentialValidationResult.INVALID_RESULT
            );
    }

    @Override
    public Set<ValidationType>
        validationTypes() {

        return Set.of(
            ValidationType.VALIDATE
        );
    }
}

Validation Result

A successful result may contain:

  • Caller name
  • Principal
  • Groups
  • Distinguished name
  • Unique identifier

Common Mistake

Returning raw database roles without validating whether the user account is active, locked, or expired.

Senior Follow-up

Identity validation should also consider account status, credential expiration, lockout, tenant context, and security audit requirements.


Q4. What is IdentityStoreHandler?

Answer

IdentityStoreHandler coordinates one or more identity stores.

An authentication mechanism can pass credentials to the handler instead of calling a specific identity store directly.

Architecture

flowchart TD
    A[Authentication Mechanism] --> B[IdentityStoreHandler]
    B --> C[Database IdentityStore]
    B --> D[LDAP IdentityStore]
    B --> E[Custom IdentityStore]
    C --> F[Credential Result]
    D --> F
    E --> F
    F --> G[Combined Caller Identity]

Example

import jakarta.inject.Inject;
import jakarta.security.enterprise.identitystore.IdentityStoreHandler;

@ApplicationScoped
public class CredentialService {

    private final IdentityStoreHandler
        identityStoreHandler;

    @Inject
    public CredentialService(
        IdentityStoreHandler identityStoreHandler
    ) {
        this.identityStoreHandler =
            identityStoreHandler;
    }

    public CredentialValidationResult validate(
        UsernamePasswordCredential credential
    ) {
        return identityStoreHandler.validate(
            credential
        );
    }
}

Benefits

  • Decouples authentication mechanism from storage
  • Supports multiple stores
  • Centralizes validation coordination
  • Allows group aggregation
  • Supports standard container behavior

Common Mistake

Hardcoding database-access logic directly inside the HTTP authentication mechanism.

Senior Follow-up

Keep HTTP credential extraction separate from identity validation and persistence concerns.


Q5. What is HttpAuthenticationMechanism?

Answer

HttpAuthenticationMechanism defines how an HTTP request is authenticated.

It can:

  • Read credentials from the request
  • Validate credentials
  • Notify the container about success
  • Reject invalid authentication
  • Redirect to a login page
  • Continue unauthenticated processing where allowed

Main Method

AuthenticationStatus validateRequest(
    HttpServletRequest request,
    HttpServletResponse response,
    HttpMessageContext context
);

Basic Authentication Mechanism Example

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.security.enterprise.AuthenticationStatus;
import jakarta.security.enterprise.authentication.mechanism.http.HttpAuthenticationMechanism;
import jakarta.security.enterprise.authentication.mechanism.http.HttpMessageContext;
import jakarta.security.enterprise.credential.UsernamePasswordCredential;
import jakarta.security.enterprise.identitystore.CredentialValidationResult;
import jakarta.security.enterprise.identitystore.IdentityStoreHandler;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@ApplicationScoped
public class CustomAuthenticationMechanism
    implements HttpAuthenticationMechanism {

    private final IdentityStoreHandler
        identityStoreHandler;

    @Inject
    public CustomAuthenticationMechanism(
        IdentityStoreHandler
            identityStoreHandler
    ) {
        this.identityStoreHandler =
            identityStoreHandler;
    }

    @Override
    public AuthenticationStatus
        validateRequest(
            HttpServletRequest request,
            HttpServletResponse response,
            HttpMessageContext context
        ) {

        String username =
            request.getParameter(
                "username"
            );

        String password =
            request.getParameter(
                "password"
            );

        if (
            username == null
            || password == null
        ) {
            return context.doNothing();
        }

        CredentialValidationResult result =
            identityStoreHandler.validate(
                new UsernamePasswordCredential(
                    username,
                    password
                )
            );

        if (
            result.getStatus()
                == CredentialValidationResult
                    .Status.VALID
        ) {
            return context
                .notifyContainerAboutLogin(
                    result
                );
        }

        return context.responseUnauthorized();
    }
}

Authentication Flow

sequenceDiagram
    participant Client
    participant Container
    participant Mechanism
    participant IdentityStore
    participant Resource
    Client->>Container: HTTP request
    Container->>Mechanism: validateRequest
    Mechanism->>IdentityStore: Validate credentials
    alt Valid
        IdentityStore-->>Mechanism: Principal and groups
        Mechanism->>Container: notifyContainerAboutLogin
        Container->>Resource: Invoke protected resource
        Resource-->>Client: Success
    else Invalid
        IdentityStore-->>Mechanism: Invalid
        Mechanism-->>Client: 401 Unauthorized
    end

Common Mistake

Logging raw passwords during authentication debugging.

Senior Follow-up

Authentication mechanisms must avoid credential leakage, timing attacks, open redirects, and inconsistent failure messages.


Q6. What is SecurityContext?

Answer

SecurityContext gives application code access to the current caller's security information.

It can be used to:

  • Get the caller principal
  • Check whether the caller is in a role
  • Check access to a web resource
  • Determine authentication status

Injection Example

import jakarta.inject.Inject;
import jakarta.security.enterprise.SecurityContext;

@ApplicationScoped
public class CurrentUserService {

    private final SecurityContext
        securityContext;

    @Inject
    public CurrentUserService(
        SecurityContext securityContext
    ) {
        this.securityContext =
            securityContext;
    }

    public String currentUsername() {
        return securityContext
            .getCallerPrincipal()
            .getName();
    }

    public boolean isAdministrator() {
        return securityContext
            .isCallerInRole("ADMIN");
    }
}

REST Resource Example

@Path("/profile")
@Produces(MediaType.APPLICATION_JSON)
public class ProfileResource {

    @Inject
    private SecurityContext
        securityContext;

    @GET
    public ProfileResponse profile() {

        String username =
            securityContext
                .getCallerPrincipal()
                .getName();

        return new ProfileResponse(
            username
        );
    }
}

Security Context Flow

flowchart TD
    A[Authenticated Request] --> B[Container Security Identity]
    B --> C[SecurityContext]
    C --> D[Caller Principal]
    C --> E[Role Checks]
    C --> F[Resource Access Check]

Common Mistake

Storing the current user in a static variable.

Senior Follow-up

Caller identity is request-specific and should be obtained from the active security context.


Q7. What is role-based access control?

Answer

Role-Based Access Control, or RBAC, grants permissions based on roles assigned to a caller.

Common Roles

  • ADMIN
  • CUSTOMER
  • SUPPORT_AGENT
  • CLAIMS_ADJUSTER
  • MANAGER
  • AUDITOR

RBAC Flow

flowchart LR
    A[User] --> B[Assigned Roles]
    B --> C[ADMIN]
    B --> D[SUPPORT_AGENT]
    C --> E[Permissions]
    D --> E
    E --> F[Protected Resources]

Example

@RolesAllowed("ADMIN")
public void deleteCustomer(
    Long customerId
) {
    customerRepository.delete(
        customerId
    );
}

Multi-Role Example

@RolesAllowed({
    "ADMIN",
    "SUPPORT_AGENT"
})
public CustomerResponse findCustomer(
    Long customerId
) {
    return customerService.findCustomer(
        customerId
    );
}

RBAC Limitations

A role may grant general capability, but the application may still need to check:

  • Record ownership
  • Geographic scope
  • Department
  • Approval amount
  • Tenant
  • Resource classification
  • Current workflow state

Example

public AccountResponse findAccount(
    Long accountId
) {

    Account account =
        accountRepository
            .findById(accountId)
            .orElseThrow();

    String caller =
        securityContext
            .getCallerPrincipal()
            .getName();

    if (
        !account.getOwnerUsername()
            .equals(caller)
        && !securityContext
            .isCallerInRole("ADMIN")
    ) {
        throw new ForbiddenException();
    }

    return accountMapper.toResponse(
        account
    );
}

Common Mistake

Assuming a CUSTOMER role allows every customer to access every customer record.

Senior Follow-up

Combine coarse-grained RBAC with fine-grained attribute or ownership checks.


Q8. What do @RolesAllowed, @PermitAll, and @DenyAll do?

Answer

These annotations define declarative method-level access control.

@RolesAllowed

Allows only specified roles.

@RolesAllowed("ADMIN")
public void suspendUser(
    Long userId
) {
}

@PermitAll

Allows all callers.

@PermitAll
public HealthResponse health() {
    return new HealthResponse("UP");
}

@DenyAll

Blocks every caller.

@DenyAll
public void deprecatedOperation() {
}

Annotation Flow

flowchart TD
    A[Method Invocation] --> B{Security Annotation}
    B -->|RolesAllowed| C[Check Caller Role]
    B -->|PermitAll| D[Allow Invocation]
    B -->|DenyAll| E[Reject Invocation]
    C --> F{Role Match?}
    F -->|Yes| D
    F -->|No| E

Example Resource

@Path("/admin/users")
@Produces(MediaType.APPLICATION_JSON)
public class AdminUserResource {

    @GET
    @RolesAllowed("ADMIN")
    public List<UserResponse> findUsers() {
        return userService.findUsers();
    }

    @GET
    @Path("/status")
    @PermitAll
    public StatusResponse status() {
        return new StatusResponse(
            "AVAILABLE"
        );
    }
}

Common Mistake

Adding @PermitAll to a class and assuming a method-level role annotation will always override it consistently without testing runtime behavior.

Senior Follow-up

Keep security annotations close to protected operations and verify enforcement through integration tests.


Q9. How is form-based authentication implemented?

Answer

Form-based authentication collects credentials through an HTML form and authenticates the user through the container.

A standard Jakarta Security mechanism can be configured with a login page and error page.

Example

import jakarta.security.enterprise.authentication.mechanism.http.FormAuthenticationMechanismDefinition;
import jakarta.security.enterprise.authentication.mechanism.http.LoginToContinue;

@FormAuthenticationMechanismDefinition(
    loginToContinue = @LoginToContinue(
        loginPage = "/login.html",
        errorPage = "/login-error.html",
        useForwardToLogin = false
    )
)
@ApplicationScoped
public class SecurityConfiguration {
}

Form Login Flow

sequenceDiagram
    participant Browser
    participant ProtectedPage
    participant LoginPage
    participant SecurityMechanism
    participant IdentityStore
    Browser->>ProtectedPage: Request protected page
    ProtectedPage-->>Browser: Redirect to login
    Browser->>LoginPage: Load login form
    Browser->>SecurityMechanism: Submit username and password
    SecurityMechanism->>IdentityStore: Validate credentials
    alt Valid
        IdentityStore-->>SecurityMechanism: Principal and roles
        SecurityMechanism-->>Browser: Redirect to original page
    else Invalid
        IdentityStore-->>SecurityMechanism: Invalid
        SecurityMechanism-->>Browser: Redirect to error page
    end

Security Considerations

  • Use HTTPS.
  • Protect against CSRF.
  • Regenerate session ID after login.
  • Use secure session cookies.
  • Avoid storing passwords in session.
  • Limit login attempts.
  • Add account lockout carefully.
  • Provide generic failure messages.

Common Mistake

Sending login credentials over HTTP.

Senior Follow-up

Modern browser applications often delegate authentication to an identity provider rather than maintaining custom password login pages.


Q10. How is basic authentication implemented?

Answer

HTTP Basic Authentication sends a username and password in the Authorization header using Base64 encoding.

Base64 is not encryption.

Therefore, Basic Authentication must be used only over HTTPS.

Example Configuration

import jakarta.security.enterprise.authentication.mechanism.http.BasicAuthenticationMechanismDefinition;

@BasicAuthenticationMechanismDefinition(
    realmName = "application-realm"
)
@ApplicationScoped
public class BasicSecurityConfiguration {
}

Header Example

Authorization: Basic dXNlcjpwYXNzd29yZA==

Flow

sequenceDiagram
    participant Client
    participant API
    participant IdentityStore
    Client->>API: Request without credentials
    API-->>Client: 401 with WWW-Authenticate
    Client->>API: Request with Basic Authorization header
    API->>IdentityStore: Validate username and password
    alt Valid
        IdentityStore-->>API: Caller identity
        API-->>Client: Protected response
    else Invalid
        IdentityStore-->>API: Invalid
        API-->>Client: 401 Unauthorized
    end

Good Use Cases

  • Internal administrative tooling
  • Simple service integration
  • Development environments
  • Controlled legacy environments

Poor Use Cases

  • Public consumer applications
  • Long-lived credentials in mobile apps
  • High-security internet-facing APIs
  • Systems requiring modern federation

Common Mistake

Assuming Base64 protects credentials.

Senior Follow-up

For modern service-to-service security, short-lived tokens or mutual TLS are often safer than reusable passwords.


Q11. How does JWT authentication work?

Answer

JWT authentication uses a signed token containing claims about the caller.

A JWT typically includes:

  • Subject
  • Issuer
  • Audience
  • Expiration
  • Issued-at timestamp
  • Roles or groups
  • Token identifier
  • Additional application claims

Token Structure

header.payload.signature

JWT Validation Flow

sequenceDiagram
    participant Client
    participant IdentityProvider
    participant API
    participant Resource
    Client->>IdentityProvider: Authenticate
    IdentityProvider-->>Client: Signed access token
    Client->>API: Authorization Bearer token
    API->>API: Validate signature
    API->>API: Validate issuer
    API->>API: Validate audience
    API->>API: Validate expiration
    API->>API: Extract roles and subject
    alt Valid
        API->>Resource: Invoke protected resource
        Resource-->>Client: Success
    else Invalid
        API-->>Client: 401 Unauthorized
    end

Authorization Header

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Important Validation Checks

  • Signature is valid
  • Algorithm is allowed
  • Token is not expired
  • Token is active
  • Issuer is trusted
  • Audience matches the API
  • Required claims exist
  • Key is current
  • Token type is appropriate

JWT Claims Example

{
  "sub": "[email protected]",
  "iss": "https://identity.example.com",
  "aud": "claims-api",
  "exp": 1783864800,
  "groups": [
    "CUSTOMER",
    "CLAIM_VIEWER"
  ]
}

Common Mistake

Only decoding the JWT and trusting its contents without validating its signature.

Senior Follow-up

JWT validation should use trusted libraries and controlled key management rather than custom cryptographic code.


Q12. How is security applied to Jakarta REST endpoints?

Answer

Jakarta REST endpoints can be protected using:

  • Security annotations
  • Request filters
  • Container security
  • Security context checks
  • Token validation
  • Fine-grained business authorization

Resource Example

@Path("/claims")
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
public class ClaimResource {

    private final ClaimService claimService;

    @Inject
    public ClaimResource(
        ClaimService claimService
    ) {
        this.claimService =
            claimService;
    }

    @GET
    @RolesAllowed({
        "CLAIM_VIEWER",
        "CLAIM_ADJUSTER"
    })
    public List<ClaimSummary> findClaims() {
        return claimService.findClaims();
    }

    @POST
    @RolesAllowed("CUSTOMER")
    public Response createClaim(
        @Valid
        CreateClaimRequest request
    ) {

        Long claimId =
            claimService.createClaim(
                request
            );

        return Response
            .status(Response.Status.CREATED)
            .entity(
                new CreateClaimResponse(
                    claimId
                )
            )
            .build();
    }

    @POST
    @Path("/{id}/approve")
    @RolesAllowed("CLAIM_ADJUSTER")
    public Response approveClaim(
        @PathParam("id")
        Long claimId
    ) {

        claimService.approveClaim(
            claimId
        );

        return Response
            .noContent()
            .build();
    }
}

REST Security Pipeline

flowchart TD
    A[HTTP Request] --> B[TLS]
    B --> C[Authentication Filter or Mechanism]
    C --> D[Token or Credential Validation]
    D --> E[Security Context]
    E --> F[Role Check]
    F --> G[Resource Ownership Check]
    G --> H[Input Validation]
    H --> I[Application Service]
    I --> J[Audit Logging]

Response Behavior

  • Unauthenticated: 401 Unauthorized
  • Authenticated but not allowed: 403 Forbidden
  • Hidden resource: sometimes 404 Not Found
  • Expired token: commonly 401 Unauthorized

Common Mistake

Returning 403 Forbidden when no caller identity exists.

Senior Follow-up

Avoid exposing whether sensitive resources exist when the caller is not authorized to know.


Q13. How should passwords be stored securely?

Answer

Passwords should never be stored in plain text or encrypted with a reversible algorithm.

They should be processed using a dedicated password-hashing algorithm designed for credential storage.

Suitable Approaches

  • Argon2
  • bcrypt
  • scrypt
  • PBKDF2

Password Storage Flow

flowchart TD
    A[User Password] --> B[Generate Unique Salt]
    B --> C[Password Hashing Algorithm]
    C --> D[Store Hash Parameters and Result]
    D --> E[Database]

Authentication Flow

sequenceDiagram
    participant User
    participant Application
    participant Database
    participant PasswordHasher
    User->>Application: Submit password
    Application->>Database: Load password hash
    Database-->>Application: Stored hash and parameters
    Application->>PasswordHasher: Verify submitted password
    PasswordHasher-->>Application: Match or no match

Example Service

@ApplicationScoped
public class PasswordService {

    public String hash(
        String rawPassword
    ) {
        // Use a trusted password-hashing library.
        throw new UnsupportedOperationException(
            "Provider implementation required"
        );
    }

    public boolean matches(
        String rawPassword,
        String storedHash
    ) {
        // Verify using the provider that created the hash.
        throw new UnsupportedOperationException(
            "Provider implementation required"
        );
    }
}

Important Practices

  • Use a unique salt for every password.
  • Configure sufficient work factor.
  • Rehash when security settings improve.
  • Never log passwords.
  • Never send passwords in URLs.
  • Do not return password hashes through APIs.
  • Protect reset tokens.
  • Apply rate limiting.

Common Mistake

Using SHA-256 directly for password storage.

Senior Follow-up

General-purpose hash functions are too fast and are not designed to resist large-scale password guessing.


Q14. What are common Jakarta Security mistakes?

Answer

Common mistakes include:

  • Storing passwords in plain text.
  • Using weak password hashing.
  • Logging credentials or tokens.
  • Trusting decoded JWT claims without signature verification.
  • Ignoring issuer or audience validation.
  • Using Basic Authentication without HTTPS.
  • Returning detailed login failure reasons.
  • Using roles without ownership checks.
  • Storing caller identity in static fields.
  • Using long-lived tokens without revocation strategy.
  • Failing to regenerate session ID after login.
  • Using insecure cookies.
  • Allowing unlimited login attempts.
  • Hardcoding secrets.
  • Treating CORS as authentication.
  • Disabling CSRF protection without understanding the client model.
  • Returning stack traces to clients.
  • Using one administrator role for every privileged action.
  • Forgetting service-to-service authentication.
  • Failing to audit security-sensitive actions.

Dangerous JWT Flow

flowchart TD
    A[Receive JWT] --> B[Base64 Decode]
    B --> C[Read Role Claim]
    C --> D[Trust Token]
    D --> E[Security Compromise]

Correct JWT Flow

flowchart TD
    A[Receive JWT] --> B[Parse Token Safely]
    B --> C[Validate Signature]
    C --> D[Validate Issuer]
    D --> E[Validate Audience]
    E --> F[Validate Expiration]
    F --> G[Validate Required Claims]
    G --> H[Create Security Identity]

Common Mistake

Assuming frontend route protection secures backend APIs.

Senior Follow-up

Security controls must be enforced on the server regardless of frontend behavior.


Q15. What are senior-level Jakarta Security best practices?

Answer

Senior developers should design security as a layered architecture rather than one annotation or filter.

Best Practices

  • Use HTTPS everywhere.
  • Delegate authentication to a trusted identity provider where practical.
  • Use short-lived access tokens.
  • Validate all token claims.
  • Use least privilege.
  • Keep roles focused and meaningful.
  • Add fine-grained resource authorization.
  • Use secure password hashing.
  • Protect secrets in a secret manager.
  • Use secure session cookies.
  • Regenerate session ID after login.
  • Apply rate limiting.
  • Implement login lockout carefully.
  • Add security audit logs.
  • Avoid logging credentials or tokens.
  • Validate redirect targets.
  • Use CSRF protection for cookie-based authentication.
  • Configure CORS narrowly.
  • Add security headers.
  • Test authorization failures.
  • Review access periodically.
  • Plan key rotation and token revocation.
  • Monitor suspicious authentication behavior.
  • Protect administrative APIs separately.
  • Design for multi-tenant isolation.

Security Design Flow

flowchart TD
    A[Identify Protected Resource] --> B[Define Caller Types]
    B --> C[Select Authentication Method]
    C --> D[Define Roles and Permissions]
    D --> E[Add Ownership and Policy Checks]
    E --> F[Define Token or Session Lifetime]
    F --> G[Add Audit Logging]
    G --> H[Add Rate Limits and Alerts]
    H --> I[Test Positive and Negative Paths]

Senior Follow-up

Security must be continuously monitored, tested, reviewed, and updated as threats and system architecture evolve.


Jakarta Security Architecture

flowchart TD
    A[Browser or API Client] --> B[TLS Endpoint]
    B --> C[Authentication Mechanism]
    C --> D[IdentityStoreHandler]
    D --> E[IdentityStore]
    E --> F[Database or Directory]
    D --> G[Principal and Groups]
    G --> H[SecurityContext]
    H --> I[Role Authorization]
    I --> J[Business Authorization]
    J --> K[Jakarta REST Resource]
    K --> L[Application Service]
    L --> M[Database]

Authentication Status

HttpAuthenticationMechanism can return authentication status values representing outcomes such as:

  • Success
  • Failure
  • Continue processing
  • Send response

Conceptual Flow

flowchart TD
    A[validateRequest] --> B{Credentials Present?}
    B -->|No| C[Do Nothing or Challenge]
    B -->|Yes| D[Validate Credentials]
    D --> E{Valid?}
    E -->|Yes| F[Notify Container About Login]
    E -->|No| G[Return Unauthorized Response]

Caller Principal

The caller principal represents the authenticated identity.

Principal principal =
    securityContext
        .getCallerPrincipal();

String callerName =
    principal.getName();

Typical Uses

  • Audit logging
  • Ownership checks
  • Tenant resolution
  • User-specific queries
  • Business rules
  • Response personalization

Warning

Do not use user-controlled request headers as a trusted principal.

Incorrect:

String currentUser =
    request.getHeader(
        "X-User"
    );

Correct:

String currentUser =
    securityContext
        .getCallerPrincipal()
        .getName();

Database Identity Model

erDiagram
    USERS ||--o{ USER_ROLES : has
    ROLES ||--o{ USER_ROLES : assigned

    USERS {
        bigint id PK
        varchar username
        varchar password_hash
        boolean active
        timestamp locked_until
    }

    ROLES {
        bigint id PK
        varchar role_name
    }

    USER_ROLES {
        bigint user_id FK
        bigint role_id FK
    }
ALTER TABLE users
ADD CONSTRAINT uk_users_username
UNIQUE (username);

ALTER TABLE roles
ADD CONSTRAINT uk_roles_role_name
UNIQUE (role_name);

Database IdentityStore Definition

Jakarta Security supports declarative database identity-store configuration.

import jakarta.security.enterprise.identitystore.DatabaseIdentityStoreDefinition;

@DatabaseIdentityStoreDefinition(
    dataSourceLookup =
        "java:app/jdbc/ApplicationDataSource",

    callerQuery =
        """
        SELECT password_hash
        FROM users
        WHERE username = ?
          AND active = true
        """,

    groupsQuery =
        """
        SELECT r.role_name
        FROM roles r
        JOIN user_roles ur
          ON ur.role_id = r.id
        JOIN users u
          ON u.id = ur.user_id
        WHERE u.username = ?
        """,

    hashAlgorithm =
        CustomPasswordHash.class
)
@ApplicationScoped
public class DatabaseSecurityConfiguration {
}

Flow

flowchart TD
    A[Username Password Credential] --> B[Database Identity Store]
    B --> C[Caller Query]
    C --> D[Password Hash Verification]
    D --> E{Valid?}
    E -->|No| F[Invalid Result]
    E -->|Yes| G[Groups Query]
    G --> H[Principal and Roles]

LDAP IdentityStore Concept

flowchart LR
    A[Authentication Mechanism] --> B[LDAP Identity Store]
    B --> C[Directory Server]
    C --> D[User Entry]
    C --> E[Group Membership]

Good Use Cases

  • Enterprise employee authentication
  • Centralized directory
  • Existing organization groups
  • Internal applications

Considerations

  • Connection security
  • Directory availability
  • Group-mapping rules
  • Nested groups
  • Search performance
  • Timeout configuration
  • Failover behavior

Custom Authentication Mechanism with Header Token

@ApplicationScoped
public class ApiTokenAuthenticationMechanism
    implements HttpAuthenticationMechanism {

    private final ApiTokenService
        apiTokenService;

    @Inject
    public ApiTokenAuthenticationMechanism(
        ApiTokenService apiTokenService
    ) {
        this.apiTokenService =
            apiTokenService;
    }

    @Override
    public AuthenticationStatus
        validateRequest(
            HttpServletRequest request,
            HttpServletResponse response,
            HttpMessageContext context
        ) {

        String token =
            request.getHeader(
                "X-API-Token"
            );

        if (token == null) {
            return context.doNothing();
        }

        return apiTokenService
            .authenticate(token)
            .map(
                identity ->
                    context
                        .notifyContainerAboutLogin(
                            identity.principal(),
                            identity.roles()
                        )
            )
            .orElseGet(
                context::responseUnauthorized
            );
    }
}

Security Warning

API tokens should be:

  • Random and high entropy
  • Stored as hashes where possible
  • Scoped
  • Rotatable
  • Expirable
  • Audited
  • Protected in transit
  • Revocable

Session-Based Authentication Flow

sequenceDiagram
    participant Browser
    participant Application
    participant IdentityStore
    participant SessionStore
    Browser->>Application: Submit credentials
    Application->>IdentityStore: Validate credentials
    alt Valid
        IdentityStore-->>Application: Principal and roles
        Application->>SessionStore: Create authenticated session
        Application-->>Browser: Secure session cookie
        Browser->>Application: Later request with cookie
        Application->>SessionStore: Resolve security identity
        Application-->>Browser: Protected response
    else Invalid
        IdentityStore-->>Application: Invalid
        Application-->>Browser: Generic login failure
    end

Token-Based Authentication Flow

sequenceDiagram
    participant Client
    participant IdentityProvider
    participant API
    Client->>IdentityProvider: Authenticate
    IdentityProvider-->>Client: Access token
    Client->>API: Bearer access token
    API->>API: Validate token
    API-->>Client: Protected response

Session vs Token

Session Authentication Token Authentication
Server stores session state Token carries claims
Uses session cookie Uses Authorization header
Easy revocation through session store Revocation may require extra strategy
Good for browser applications Good for APIs and distributed systems
CSRF protection needed for cookies Bearer-token theft remains a risk
Central session control Easier horizontal scaling

JWT Header and Payload

{
  "alg": "RS256",
  "typ": "JWT",
  "kid": "key-2026-07"
}

Payload

{
  "sub": "user-101",
  "iss": "https://id.example.com",
  "aud": "order-api",
  "iat": 1783857600,
  "exp": 1783861200,
  "jti": "token-abc-101",
  "groups": [
    "CUSTOMER"
  ]
}

Signature

The signature protects token integrity.

It does not encrypt the payload.

Important

Do not place secrets or sensitive personal data inside a JWT unless the token is additionally encrypted and the architecture requires it.


JWT Key Rotation

flowchart TD
    A[Identity Provider] --> B[Current Signing Key]
    A --> C[Previous Verification Key]
    B --> D[Issue New Tokens]
    C --> E[Verify Older Unexpired Tokens]
    D --> F[Publish Key Set]
    E --> F
    F --> G[API Retrieves Trusted Keys]

Best Practices

  • Use key identifiers.
  • Publish trusted public keys securely.
  • Cache keys with refresh policy.
  • Support overlapping rotation.
  • Reject unknown algorithms.
  • Monitor key-fetch failures.
  • Remove old keys after token expiration window.

Access Token vs Refresh Token

Access Token Refresh Token
Short lifetime Longer lifetime
Sent to APIs Sent only to token endpoint
Contains API authorization claims Used to obtain new access token
Higher exposure frequency Must be stored more securely
Usually bearer token Often rotated

Common Mistake

Sending refresh tokens to normal application APIs.


Token Revocation Strategies

  • Short token lifetime
  • Token denylist
  • Session-bound tokens
  • Token introspection
  • User security version
  • Key rotation
  • Refresh-token revocation
  • Account disable checks

Revocation Flow

flowchart TD
    A[Token Presented] --> B[Validate Signature and Claims]
    B --> C{Revocation Check Required?}
    C -->|No| D[Allow]
    C -->|Yes| E[Check Token Status]
    E --> F{Revoked?}
    F -->|Yes| G[Reject]
    F -->|No| D

Fine-Grained Authorization

RBAC answers broad questions.

Fine-grained authorization evaluates resource attributes and business rules.

Example Policy

A claims adjuster may approve a claim only when:

- The caller has CLAIM_ADJUSTER role.
- The claim belongs to the caller's region.
- The claim amount is below the caller's approval limit.
- The claim is currently in REVIEW status.

Flow

flowchart TD
    A[Approve Claim Request] --> B[Check CLAIM_ADJUSTER Role]
    B --> C[Load Claim]
    C --> D[Check Region]
    D --> E[Check Approval Limit]
    E --> F[Check Workflow Status]
    F --> G{All Checks Pass?}
    G -->|Yes| H[Approve Claim]
    G -->|No| I[Reject with 403 or Business Error]

Service Example

@Transactional
public void approveClaim(
    Long claimId
) {

    Claim claim =
        claimRepository
            .findById(claimId)
            .orElseThrow();

    UserAuthorizationProfile profile =
        authorizationService
            .currentProfile();

    if (
        !securityContext.isCallerInRole(
            "CLAIM_ADJUSTER"
        )
    ) {
        throw new ForbiddenException();
    }

    if (
        !claim.getRegion()
            .equals(profile.region())
    ) {
        throw new ForbiddenException();
    }

    if (
        claim.getAmount()
            .compareTo(
                profile.approvalLimit()
            ) > 0
    ) {
        throw new ForbiddenException();
    }

    claim.approve();
}

Multi-Tenant Authorization

Every tenant-specific query should enforce tenant isolation.

Unsafe Query

entityManager.find(
    Customer.class,
    customerId
);

Safer Query

Customer customer =
    entityManager.createQuery(
        """
        select c
        from Customer c
        where c.id = :customerId
          and c.tenantId = :tenantId
        """,
        Customer.class
    )
    .setParameter(
        "customerId",
        customerId
    )
    .setParameter(
        "tenantId",
        currentTenantId
    )
    .getSingleResult();

Tenant Flow

flowchart TD
    A[Authenticated Caller] --> B[Resolve Trusted Tenant]
    B --> C[Apply Tenant Filter]
    C --> D[Query Tenant-Owned Resource]
    D --> E{Resource in Tenant?}
    E -->|Yes| F[Continue]
    E -->|No| G[Reject or Return Not Found]

Common Mistake

Trusting a tenant ID directly from an unvalidated request header.


Secure Cookie Configuration

Important cookie attributes include:

  • Secure
  • HttpOnly
  • SameSite
  • Limited path
  • Limited domain
  • Appropriate lifetime

Conceptual Header

Set-Cookie:
SESSION=abc123;
Secure;
HttpOnly;
SameSite=Lax;
Path=/;
Max-Age=1800
flowchart TD
    A[Session Cookie] --> B[Secure]
    A --> C[HttpOnly]
    A --> D[SameSite]
    A --> E[Short Lifetime]
    A --> F[Server-Side Revocation]

CSRF Protection

CSRF is primarily a concern when browsers automatically attach credentials such as cookies.

Attack Flow

sequenceDiagram
    participant User
    participant MaliciousSite
    participant Bank
    User->>Bank: Login and receive session cookie
    User->>MaliciousSite: Visit malicious page
    MaliciousSite->>Bank: Forged request
    Note over Bank: Browser automatically attaches cookie

Defenses

  • CSRF tokens
  • SameSite cookies
  • Origin validation
  • Referer validation where appropriate
  • Re-authentication for sensitive actions
  • Avoid state changes through GET
  • Use Authorization header tokens where suitable

Common Mistake

Assuming CORS prevents CSRF.


CORS Security

CORS controls which browser origins may access responses.

It is not authentication.

Safer Configuration

  • Allow only trusted origins.
  • Limit methods.
  • Limit headers.
  • Avoid wildcard origin with credentials.
  • Validate preflight behavior.
  • Do not reflect arbitrary origins.

Flow

flowchart TD
    A[Browser Cross-Origin Request] --> B[Origin Header]
    B --> C[Server CORS Policy]
    C --> D{Origin Allowed?}
    D -->|Yes| E[Return CORS Headers]
    D -->|No| F[Browser Blocks Response Access]

Security Headers

Common security headers include:

  • Content Security Policy
  • X-Content-Type-Options
  • Strict-Transport-Security
  • Referrer-Policy
  • Permissions-Policy
  • Frame restrictions

Response Filter Example

@Provider
public class SecurityHeadersFilter
    implements ContainerResponseFilter {

    @Override
    public void filter(
        ContainerRequestContext request,
        ContainerResponseContext response
    ) {

        response
            .getHeaders()
            .putSingle(
                "X-Content-Type-Options",
                "nosniff"
            );

        response
            .getHeaders()
            .putSingle(
                "Referrer-Policy",
                "no-referrer"
            );

        response
            .getHeaders()
            .putSingle(
                "Content-Security-Policy",
                "default-src 'self'"
            );
    }
}

Rate Limiting Login Attempts

flowchart TD
    A[Login Attempt] --> B[Identify Account and Source]
    B --> C[Increment Attempt Counter]
    C --> D{Limit Exceeded?}
    D -->|No| E[Validate Credentials]
    D -->|Yes| F[Delay or Reject]
    E --> G{Valid?}
    G -->|Yes| H[Reset or Reduce Counter]
    G -->|No| I[Record Failure]

Important

Avoid permanent denial-of-service through careless account lockout.

Consider:

  • Progressive delays
  • Temporary lockout
  • Device reputation
  • IP reputation
  • MFA
  • User notification
  • Administrative recovery

Multi-Factor Authentication

MFA combines at least two factor categories:

  • Something the user knows
  • Something the user has
  • Something the user is

Flow

sequenceDiagram
    participant User
    participant LoginService
    participant IdentityStore
    participant MFAService
    User->>LoginService: Username and password
    LoginService->>IdentityStore: Validate password
    IdentityStore-->>LoginService: Valid
    LoginService->>MFAService: Request second factor
    MFAService-->>User: Challenge
    User->>MFAService: Submit code
    MFAService-->>LoginService: Verified
    LoginService-->>User: Authentication complete

Audit Logging

Security-sensitive actions should be audited.

Common Audit Events

  • Login success
  • Login failure
  • Password reset
  • MFA change
  • Role assignment
  • Account lock
  • Privileged data access
  • Administrative update
  • Token revocation
  • DLQ replay
  • Security-policy change

Audit Record

public record SecurityAuditEvent(
    String eventType,
    String actor,
    String target,
    Instant occurredAt,
    String correlationId,
    String outcome
) {
}

Important

Do not include:

  • Plain-text passwords
  • Full access tokens
  • Session IDs
  • Private keys
  • Sensitive personal content

Generic Authentication Failure

Unsafe:

Password is incorrect.

Safer:

Invalid username or password.

Why?

Detailed failures can reveal:

  • Whether an account exists
  • Whether an account is locked
  • Whether the password was correct
  • Whether MFA is enabled

Internal logs may retain more detail, but client responses should be carefully designed.


Secret Management

Do not hardcode:

  • Database passwords
  • JWT private keys
  • API tokens
  • Encryption keys
  • OAuth client secrets
flowchart TD
    A[Application Startup] --> B[Secret Manager]
    B --> C[Retrieve Authorized Secret]
    C --> D[Use in Memory]
    D --> E[Rotate Secret]
    E --> F[Refresh Application Safely]

Good Practices

  • Least-privilege access
  • Rotation
  • Auditing
  • Environment separation
  • No source-control storage
  • No logs
  • Short-lived credentials where possible

OAuth 2.0 and OpenID Connect Context

OAuth 2.0 is commonly used for delegated authorization.

OpenID Connect adds identity information on top of OAuth 2.0.

Architecture

sequenceDiagram
    participant User
    participant Client
    participant IdentityProvider
    participant API
    User->>Client: Start login
    Client->>IdentityProvider: Authorization request
    IdentityProvider->>User: Authenticate
    IdentityProvider-->>Client: Authorization result
    Client->>IdentityProvider: Exchange for tokens
    IdentityProvider-->>Client: ID token and access token
    Client->>API: Access token
    API->>API: Validate token and authorize
    API-->>Client: Protected data

Important Distinction

  • ID token identifies the user to the client.
  • Access token authorizes calls to the API.
  • Refresh token obtains new access tokens.
  • An ID token should not automatically be treated as an API access token.

Service-to-Service Security

Common approaches include:

  • OAuth client credentials
  • Mutual TLS
  • Signed service tokens
  • Workload identity
  • Short-lived platform credentials

Flow

sequenceDiagram
    participant ServiceA
    participant IdentityProvider
    participant ServiceB
    ServiceA->>IdentityProvider: Client authentication
    IdentityProvider-->>ServiceA: Short-lived access token
    ServiceA->>ServiceB: Bearer token
    ServiceB->>ServiceB: Validate service identity
    ServiceB-->>ServiceA: Protected response

Common Mistake

Using one shared static API key across all services.


Security Testing Strategy

Test:

  • Successful authentication
  • Invalid credentials
  • Locked account
  • Expired account
  • Missing token
  • Expired token
  • Wrong issuer
  • Wrong audience
  • Invalid signature
  • Missing role
  • Wrong tenant
  • Wrong resource owner
  • Admin-only operation
  • Session fixation protection
  • CSRF failure
  • CORS restrictions
  • Rate limiting
  • Audit generation

Test Matrix

flowchart TD
    A[Security Test Suite] --> B[Authentication Tests]
    A --> C[Authorization Tests]
    A --> D[Token Validation Tests]
    A --> E[Session Tests]
    A --> F[Tenant Isolation Tests]
    A --> G[Audit Tests]

Authorization Integration Test Example

@Test
void customerMustNotAccessAnotherCustomersAccount() {

    String customerAToken =
        tokenFactory.issueToken(
            "customer-a",
            Set.of("CUSTOMER")
        );

    given()
        .header(
            "Authorization",
            "Bearer " + customerAToken
        )
        .when()
        .get(
            "/accounts/customer-b-account"
        )
        .then()
        .statusCode(403);
}

The exact testing library depends on the project, but negative authorization tests are essential.


Threat Modeling

A simple threat-modeling process asks:

  • What are the assets?
  • Who are the actors?
  • What are the trust boundaries?
  • How can authentication fail?
  • How can authorization fail?
  • What data could be exposed?
  • What dependencies can be abused?
  • What must be audited?
  • How will incidents be detected?

Threat Model Flow

flowchart TD
    A[Identify Assets] --> B[Identify Attackers]
    B --> C[Map Data Flows]
    C --> D[Identify Trust Boundaries]
    D --> E[Identify Threats]
    E --> F[Define Controls]
    F --> G[Test Controls]
    G --> H[Monitor Residual Risk]

Security Layers

flowchart TD
    A[Network Security] --> B[TLS]
    B --> C[Authentication]
    C --> D[Authorization]
    D --> E[Input Validation]
    E --> F[Business Rules]
    F --> G[Database Constraints]
    G --> H[Audit and Monitoring]

No single control is sufficient.


Production Security Architecture

flowchart TD
    A[Client] --> B[API Gateway]
    B --> C[TLS Termination]
    C --> D[Rate Limiting]
    D --> E[Token Validation]
    E --> F[Jakarta REST API]
    F --> G[SecurityContext]
    G --> H[Role Check]
    H --> I[Ownership and Policy Check]
    I --> J[Application Service]
    J --> K[Database]
    J --> L[Audit Event]
    L --> M[Security Monitoring]

Authentication Decision Matrix

Scenario Recommended Approach
Browser enterprise application OpenID Connect
Public mobile application OAuth 2.0 with PKCE
Internal REST API Short-lived bearer token
Service-to-service Client credentials or workload identity
Legacy internal tool Basic authentication over TLS, if unavoidable
Administrative portal Strong authentication with MFA
Consumer password login Prefer dedicated identity provider
Machine integration Scoped API credential or OAuth client

Authorization Decision Matrix

Requirement Recommended Control
Admin-only endpoint Role check
User's own record Ownership check
Regional access Attribute check
Approval amount Business-policy check
Tenant isolation Tenant-scoped query
Sensitive operation Step-up authentication
Shared service permission Scope or service role
Record classification Policy-based authorization

Common Jakarta Security Anti-Patterns

Frontend-Only Authorization

Hide the Admin button in the UI.

This does not protect the backend.

Client-Supplied Role

X-Role: ADMIN

Never trust client-supplied authorization claims without cryptographic or trusted gateway validation.

Long-Lived Bearer Token

A stolen bearer token remains usable until it expires or is revoked.

Role Explosion

ADMIN_READ_CUSTOMER_US_EAST_TIER_1
ADMIN_READ_CUSTOMER_US_EAST_TIER_2
...

Excessively granular roles become difficult to manage.

Use policy or attributes for dynamic conditions.


Error Response Examples

Unauthenticated

{
  "code": "UNAUTHENTICATED",
  "message": "Authentication is required",
  "correlationId": "req-1001"
}

Forbidden

{
  "code": "FORBIDDEN",
  "message": "You do not have permission to perform this action",
  "correlationId": "req-1002"
}

Avoid revealing sensitive authorization details.


Security Monitoring Metrics

Monitor:

  • Login success rate
  • Login failure rate
  • Locked accounts
  • Token-validation failures
  • Invalid signatures
  • Expired tokens
  • Wrong-audience attempts
  • Forbidden-response rate
  • Administrative operations
  • Password-reset volume
  • MFA failures
  • Rate-limit triggers
  • Suspicious IP activity
  • Tenant-isolation failures
  • Session creation and revocation
  • Security audit pipeline health

Monitoring Flow

flowchart TD
    A[Security Event] --> B[Structured Audit Log]
    B --> C[Security Analytics]
    C --> D[Detection Rule]
    D --> E{Suspicious?}
    E -->|Yes| F[Alert]
    E -->|No| G[Store for Investigation]

Incident Response Preparation

Plan for:

  • Compromised account
  • Stolen token
  • Leaked signing key
  • Exposed API credential
  • Unauthorized role assignment
  • Session theft
  • Mass login attack
  • Tenant data exposure

Response Flow

flowchart TD
    A[Security Incident Detected] --> B[Contain]
    B --> C[Revoke Credentials]
    C --> D[Rotate Keys]
    D --> E[Preserve Evidence]
    E --> F[Assess Impact]
    F --> G[Notify Stakeholders]
    G --> H[Remediate Root Cause]
    H --> I[Improve Controls]

Jakarta Security Checklist

Authentication

  • Trusted credential source
  • Secure transport
  • Strong password hashing
  • MFA where appropriate
  • Generic failure responses
  • Rate limiting
  • Account status checks

Authorization

  • Least privilege
  • Role checks
  • Ownership checks
  • Tenant isolation
  • Workflow checks
  • Sensitive-operation protection

Tokens

  • Signature validation
  • Issuer validation
  • Audience validation
  • Expiration validation
  • Algorithm allowlist
  • Key rotation
  • Revocation strategy

Sessions

  • Secure cookies
  • HttpOnly
  • SameSite
  • Session-ID rotation
  • Idle timeout
  • Absolute timeout
  • Server-side invalidation

Operations

  • Audit logs
  • Alerts
  • Secret rotation
  • Security testing
  • Access reviews
  • Incident response

Senior Security Checklist

Trusted Authentication Source
        │
        ▼
Short-Lived Identity
        │
        ▼
Least-Privilege Roles
        │
        ▼
Ownership and Policy Checks
        │
        ▼
Secure Token or Session Handling
        │
        ▼
Audit and Monitoring
        │
        ▼
Key and Secret Rotation
        │
        ▼
Negative Security Testing

Interview Quick Revision

Concept Purpose
Jakarta Security Standard application security API
Authentication Verify caller identity
Authorization Verify caller permission
IdentityStore Validate credentials and groups
IdentityStoreHandler Coordinate identity stores
HttpAuthenticationMechanism Authenticate HTTP requests
SecurityContext Access current caller identity
Principal Authenticated caller
Role Group of permissions
@RolesAllowed Restrict by role
@PermitAll Allow all callers
@DenyAll Deny all callers
JWT Signed token format
RBAC Role-based access control
Fine-Grained Authorization Resource and policy checks

Key Takeaways

  • Jakarta Security provides a standardized authentication and identity-store model for Jakarta EE applications.
  • Authentication verifies who the caller is.
  • Authorization verifies what the caller may do.
  • IdentityStore validates credentials and provides caller groups.
  • IdentityStoreHandler coordinates one or more identity stores.
  • HttpAuthenticationMechanism handles HTTP credential extraction and login communication with the container.
  • SecurityContext exposes the authenticated principal and role information.
  • Role-based access control provides coarse-grained authorization.
  • Fine-grained ownership, tenant, region, amount, and workflow checks are often required in addition to roles.
  • @RolesAllowed, @PermitAll, and @DenyAll provide declarative method-level access control.
  • Form authentication requires HTTPS, secure sessions, CSRF protection, and session-ID regeneration.
  • Basic Authentication sends reusable credentials and must never be used without TLS.
  • JWT authentication requires signature, issuer, audience, expiration, algorithm, and claim validation.
  • JWT payloads are signed but not automatically encrypted.
  • Access tokens, ID tokens, and refresh tokens serve different purposes.
  • Passwords must be stored with a dedicated password-hashing algorithm such as Argon2, bcrypt, scrypt, or PBKDF2.
  • CORS is not an authentication or authorization mechanism.
  • CSRF protection is especially important for cookie-based authentication.
  • Secure cookies require Secure, HttpOnly, and appropriate SameSite settings.
  • Secrets, keys, and client credentials should be stored in a secure secret-management platform.
  • Service-to-service authentication should use scoped, short-lived credentials where possible.
  • Security-sensitive actions should produce structured audit events.
  • Production security requires defense in depth, threat modeling, negative testing, monitoring, key rotation, and incident-response planning.