I've been thinking about this a lot while building Shiplogue, especially as I've worked on its cloud infrastructure, project-based access, and integrations.

Recently, I came across a JetBrains tutorial titled Secure Your APIs: OAuth2 and JWT for Beginners, and I thought it was worth sharing.

What the tutorial covers

The tutorial walks through securing REST APIs using OAuth 2.0 and JSON Web Tokens (JWT), with a practical Kotlin and Spring Boot implementation.

It covers:

  • The difference between authentication and authorization.
  • How OAuth 2.0 handles delegated authorization.
  • JWT structure, claims, signatures, and bearer tokens.
  • Protecting API endpoints using Spring Security.
  • Combining scopes, roles, and custom permissions.
  • Validating token signatures, issuers, audiences, and expiration.
  • Token expiration and revocation strategies.

One distinction I particularly appreciated was that OAuth 2.0 and JWT aren't competing technologies.

OAuth 2.0 provides an authorization framework, while JWT is a token format that can carry verifiable claims.

Understanding where each fits makes designing secure APIs considerably easier.

How building Shiplogue has made this more practical for me

Shiplogue is a developer productivity tool that captures commits, coding-agent activity, and reviews, then compiles them into daily standups that developers can review and share.

shiplogue standup via IDE extension

It works across VS Code, Cursor, and Antigravity, etc., with cloud delivery to Slack, Discord, and Microsoft Teams etc.

As the product has grown beyond a local IDE extension into a cloud-backed service, security has become a much more tangible engineering responsibility.

For example, some of the decisions I've had to account for include:

1. Protecting credentials

Shiplogue uses editor SecretStorage, backed by the operating system's keychain, for provider and connector keys.

2. Project-level isolation

Connector keys are scoped to individual projects, hashed at rest, and can be rotated. This is important when different projects and integrations have different access requirements.

3. Data minimisation

Shiplogue follows a local-first approach. Source code, prompts, and terminal output stay on the developer's machine. Only sanitised activity metadata and diff summaries are synced when cloud sync is enabled.

4. Access control

Dashboard access is restricted to authenticated workspace members. Protecting data isn't just about securing the connection; it's also about ensuring the right people can access the right resources.

These are some of the architectural considerations that have shaped how I'm approaching the product.

I'm not suggesting that OAuth 2.0 and JWT alone solve every security problem, either. They're pieces of a much bigger security model.

What stood out to me

My biggest takeaway from the JetBrains tutorial is that validating a token is not the same as authorizing an action.

A token can have a valid signature and still be inappropriate for your application.

You need to consider its issuer, audience, expiration, scopes, roles, and the actual resource being accessed.

That distinction becomes increasingly important as applications grow and introduce more integrations, users, and permission levels.

Further reading and resources

If you're building REST APIs or working with backend security, I'd recommend going through the original tutorial. It includes practical Kotlin and Spring Boot examples.

The main resource:

Secure Your APIs: OAuth2 and JWT for Beginners — JetBrains

If you're curious about what I'm building alongside these explorations:

I'd also be interested in hearing how other developers approach API security, particularly project-level permissions and credential management in multi-tenant applications.

What security considerations do you prioritise when moving a local-first tool into the cloud?