Skip to content

Commit 5d1aceb

Browse files
Kapil GowruKapil Gowru
authored andcommitted
fix: merged with master
2 parents ed10bab + 8d4937d commit 5d1aceb

File tree

4 files changed

+237
-43
lines changed

4 files changed

+237
-43
lines changed

fern/fern.config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
{
22
"organization": "fern",
3-
"version": "0.64.22"
4-
}
3+
"version": "0.65.23"
4+
}

fern/products/docs/docs.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ navigation:
162162
contents:
163163
- page: SSO
164164
path: ./pages/authentication/sso.mdx
165-
- page: RBAC
165+
- page: Role based access control (RBAC)
166166
path: ./pages/authentication/rbac.mdx
167167
- page: API Key Injection
168168
path: ./pages/api-references/autopopulate-api-key.mdx

fern/products/docs/pages/authentication/rbac.mdx

Lines changed: 139 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,59 +6,87 @@ description: Learn how to restrict access to your documentation using role-based
66

77
<Note>RBAC is part of the pro plan.</Note>
88

9-
Fern allows you to restrict parts of your navigation to individuals with specific roles. Below, we walk through each of the steps
10-
required to configure RBAC.
9+
## Introduction
10+
11+
Fern allows you to restrict parts of your navigation to individuals with specific roles. RBAC enables you to create different levels of access for different user types within your documentation.
12+
13+
### Use cases
14+
15+
Role-based access control is helpful for scenarios such as:
16+
17+
- **Partner documentation**: Provide exclusive API documentation to integration partners while keeping internal docs private
18+
- **Beta features**: Share new features with beta users before general release
19+
- **Internal documentation**: Restrict sensitive documentation to employees only
20+
- **Tiered access**: Offer different documentation levels based on subscription tiers
21+
- **Customer-specific content**: Show different documentation based on customer type or plan
22+
23+
### How it works
24+
25+
If a user visits content not marked as visible to the `everyone` role, Fern will check for an authentication cookie to indicate what roles that user has. If the user does not have a role matching the viewers of the page, we will redirect them to the URL you provided during setup.
26+
27+
Below, we walk through each of the steps required to configure RBAC.
28+
29+
### Architecture diagram
30+
31+
```mermaid
32+
sequenceDiagram
33+
participant U as User
34+
participant F as Fern Docs
35+
participant R as Redirect URL
36+
participant A as Auth System
37+
38+
U->>F: Visit restricted page
39+
F->>F: Check fern_token cookie
40+
41+
alt Cookie exists
42+
F->>F: Decode JWT with secret key
43+
F->>F: Extract roles from JWT
44+
F->>F: Check if user has required role
45+
46+
alt User has required role
47+
F->>U: Show restricted content
48+
else User lacks required role
49+
F->>U: User is shown a 404 page
50+
end
51+
else No cookie
52+
F->>R: Redirect to login page
53+
R->>A: Authenticate user
54+
end
55+
56+
Note over A: User logs in
57+
58+
A->>A: Generate JWT with roles
59+
A->>F: Set fern_token cookie
60+
F->>F: Validate JWT and roles
61+
F->>U: Show restricted content
62+
```
63+
64+
## Set up RBAC
1165

1266
<Steps>
1367
### Define all the `roles` in your docs.yml
1468

15-
Start by defining all the different roles in your `docs.yml`. You can simply specify this under a `roles` key:
69+
Start by defining all the different roles in your `docs.yml`. You can specify this under a `roles` key:
1670

1771
```yml docs.yml
1872
roles:
19-
- everyone # every user is given this role
20-
- partners
21-
- beta-users
22-
- admins
23-
```
24-
25-
<Info>The `everyone` role is a special role. Every user has this role.</Info>
26-
27-
### Define viewers on parts of the navigation
28-
29-
Every navigation item (`sections`, `pages`, `api references`) can have a set of designated viewers. If you don't
30-
specify viewers, then it defaults to `everyone` and the page is public.
31-
32-
```yml docs.yml {7-8,14-16}
33-
navigation:
34-
- tab: Documentation
35-
layout:
36-
- page: Overview
37-
path: pages/overview.mdx
38-
- section: Beta Release
39-
viewers:
40-
- beta-users
41-
- tab: API Reference
42-
layout:
43-
- page: Overview
44-
path: pages/overview.mdx
45-
- section: Beta Release
46-
viewers:
47-
- partners
48-
- admin
73+
- everyone # every user is given this role
74+
- partners
75+
- beta-users
76+
- admins
4977
```
5078
51-
The viewers are inherited by nested pieces of content. For example, if a section can only be viewed by `admins`, then all its
52-
pages and nested sections can also only be viewed by admins.
79+
<Info>
80+
The `everyone` role is special. Every user has this role (including unauthenticated users).
81+
</Info>
5382

5483
### Configure authentication via a `fern_token`
5584

5685
In this step, we will configure authentication so that Fern can understand what roles a particular user has. Fern expects the user's
5786
browser session to have a cookie called `fern_token`. If the cookie is not present, the user will be redirected to your company's
5887
login page.
5988

60-
Upon login, you must set a JWT for the user using a secret key that we will provide you with. The JWT must have a `fern` claim
61-
with a key called roles.
89+
**You are responsible for creating and setting the `fern_token` cookie in your authentication system.** Upon login, you must set a JWT for the user using a secret key that we will provide. The JWT must have a `fern` claim with a key called `roles`.
6290

6391
```json
6492
{
@@ -68,6 +96,79 @@ with a key called roles.
6896
}
6997
```
7098

71-
<Note>Please reach out to [email protected] when you are on this step so we can provide you with a secret key.</Note>
99+
### Contact Fern for setup
100+
101+
When you're ready to implement RBAC, **contact [email protected]** to receive your secret key for JWT signing.
102+
103+
You'll also need to provide the URL where Fern should send unauthenticated users to log in.
104+
105+
<Note>Optional: If you'd like restricted pages to be visible but locked to unauthenticated users (rather than completely hidden), let us know during this step.</Note>
72106

73107
</Steps>
108+
109+
### Access control within navigation
110+
111+
You can designate viewers on the following navigation items:
112+
- `products`
113+
- `versions`
114+
- `tabs`
115+
- `sections`
116+
- `pages`
117+
- `api references`
118+
- `changelogs`
119+
120+
If you don't specify viewers, the content will be visible to _any authenticated user_.
121+
122+
```yml docs.yml {6-7, 13-15}
123+
navigation:
124+
- tab: Home
125+
layout:
126+
- page: Welcome # this page is public
127+
path: pages/welcome.mdx
128+
viewer:
129+
- everyone
130+
- tab: Documentation
131+
layout:
132+
- page: Overview # this page is visible to all logged-in users
133+
path: pages/overview.mdx
134+
- section: Beta Release # this section is visible to beta-users and admins
135+
viewers:
136+
- beta-users
137+
- admins
138+
contents:
139+
...
140+
```
141+
142+
Viewership is inherited. For example, if a section can only be viewed by `admins`, then all its pages and nested sections can also only be viewed by admins.
143+
144+
### Access control within MDX pages
145+
146+
You can restrict specific content within your MDX pages to users with certain roles. This allows you to show different content to different user types on the same page.
147+
148+
#### Basic usage
149+
150+
Use the `<If />` component to conditionally render content based on user roles:
151+
152+
```mdx
153+
<If roles={["beta-users"]}>
154+
<Callout>
155+
This callout is only visible to beta users.
156+
</Callout>
157+
</If>
158+
```
159+
160+
#### Multiple roles
161+
162+
You can specify multiple roles. Content will be visible to users who have **any** of the specified roles:
163+
164+
```mdx
165+
<If roles={["partners", "admins"]}>
166+
<Callout>
167+
This content is visible to both partners and admins.
168+
</Callout>
169+
</If>
170+
```
171+
172+
<Note>
173+
The `<If>` component respects the same role inheritance rules as navigation items. If a user has access to a page, they can see all content on that page that matches their roles.
174+
</Note>

fern/products/sdks/guides/configure-global-headers.mdx

Lines changed: 95 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,99 @@ title: Configure Global Headers
33
description: Guide to configuring global headers in your SDKs.
44
---
55

6-
Learn how to configure global headers for all requests made by your SDKs.
6+
Your API may leverage certain headers for every endpoint or most endpoints.
7+
These are called **global headers**.
78

8-
<Warning>Docs are coming soon for this page.<br/><br/>Please [book a demo](https://buildwithfern.com/book-demo) or [reach out to us](https://buildwithfern.com/book-demo) to get set up with this feature. </Warning>
9+
## How it works for SDK users
10+
11+
Once you configure a global header (either automatically detected or manually
12+
specified), Fern generates an SDK that accepts this as a constructor parameter.
13+
Users can then provide the value once, and the generated SDK automatically
14+
includes the header in all their API calls:
15+
16+
```python
17+
import os
18+
19+
class Client:
20+
21+
def __init__(self, *, apiKey: str):
22+
```
23+
24+
## Specifying global headers
25+
26+
Fern automatically identifies headers that are used in every request, or the
27+
majority of requests, and marks them as global. You can manually configure additional
28+
global headers in either `api.yml` (Fern Definition) or `openapi.yml`.
29+
30+
<AccordionGroup>
31+
<Accordion title="Fern Definition">
32+
33+
To specify headers that are meant to be included on every request:
34+
35+
<CodeBlock title="api.yml">
36+
```yaml {3}
37+
name: api
38+
headers:
39+
X-App-Id: string
40+
```
41+
</CodeBlock>
42+
43+
### Global path parameters
44+
You can also specify path parameters that are meant to be included on every request:
45+
46+
<CodeBlock title="api.yml">
47+
```yaml
48+
name: api
49+
base-path: /{userId}/{orgId}
50+
path-parameters:
51+
userId: string
52+
orgId: string
53+
```
54+
</CodeBlock>
55+
56+
#### Overriding the base path
57+
58+
If you have certain endpoints that do not live at the configured `base-path`, you can
59+
override the `base-path` at the endpoint level.
60+
61+
```yml imdb.yml {5}
62+
service:
63+
endpoints:
64+
getMovie:
65+
method: POST
66+
base-path: "override/{arg}"
67+
path: "movies/{movieId}"
68+
path-parameters:
69+
arg: string
70+
```
71+
72+
<Note>
73+
You cannot yet specify query parameters that are meant to be included on every request.
74+
If you'd like to see this feature, please upvote [this issue](https://github.com/fern-api/fern/issues/2930).
75+
</Note>
76+
77+
</Accordion>
78+
<Accordion title="OpenAPI">
79+
80+
Use the `x-fern-global-headers` extension to label additional headers as global
81+
or to alias the names of global headers:
82+
83+
```yaml title="openapi.yml"
84+
x-fern-global-headers:
85+
- header: custom_api_key
86+
name: api_key
87+
- header: userpool_id
88+
optional: true
89+
```
90+
91+
This configuration yields the following client:
92+
93+
```python
94+
import os
95+
96+
class Client:
97+
98+
def __init__(self, *, apiKey: str, userpoolId: typing.Optional[str])
99+
```
100+
</Accordion>
101+
</AccordionGroup>

0 commit comments

Comments
 (0)