mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2024-10-11 18:07:24 +08:00
Run prettier
This commit is contained in:
parent
d081ecf5b3
commit
7434ff71eb
7
.prettierignore
Normal file
7
.prettierignore
Normal file
@ -0,0 +1,7 @@
|
||||
app-dist
|
||||
dist
|
||||
.idea
|
||||
.github
|
||||
public
|
||||
node_modules
|
||||
pnpm-lock.yaml
|
@ -26,7 +26,7 @@ export default defineConfig({
|
||||
'https://github.com/kamranahmedse',
|
||||
'https://thenewstack.io',
|
||||
'https://cs.fyi',
|
||||
'https://roadmap.sh'
|
||||
'https://roadmap.sh',
|
||||
];
|
||||
|
||||
if (whiteListedStarts.some((start) => href.startsWith(start))) {
|
||||
|
@ -3,7 +3,10 @@ const path = require('path');
|
||||
|
||||
const CONTENT_DIR = path.join(__dirname, '../content');
|
||||
// Directory containing the best-practices
|
||||
const BEST_PRACTICE_CONTENT_DIR = path.join(__dirname, '../src/data/best-practices');
|
||||
const BEST_PRACTICE_CONTENT_DIR = path.join(
|
||||
__dirname,
|
||||
'../src/data/best-practices'
|
||||
);
|
||||
const bestPracticeId = process.argv[2];
|
||||
|
||||
const allowedBestPracticeId = fs.readdirSync(BEST_PRACTICE_CONTENT_DIR);
|
||||
@ -28,7 +31,10 @@ if (!bestPracticeDirName) {
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const bestPracticeDirPath = path.join(BEST_PRACTICE_CONTENT_DIR, bestPracticeDirName);
|
||||
const bestPracticeDirPath = path.join(
|
||||
BEST_PRACTICE_CONTENT_DIR,
|
||||
bestPracticeDirName
|
||||
);
|
||||
const bestPracticeContentDirPath = path.join(
|
||||
BEST_PRACTICE_CONTENT_DIR,
|
||||
bestPracticeDirName,
|
||||
@ -37,7 +43,9 @@ const bestPracticeContentDirPath = path.join(
|
||||
|
||||
// If best practice content already exists do not proceed as it would override the files
|
||||
if (fs.existsSync(bestPracticeContentDirPath)) {
|
||||
console.error(`Best Practice content already exists @ ${bestPracticeContentDirPath}`);
|
||||
console.error(
|
||||
`Best Practice content already exists @ ${bestPracticeContentDirPath}`
|
||||
);
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
@ -51,7 +59,11 @@ function prepareDirTree(control, dirTree) {
|
||||
const controlName = control?.properties?.controlName || '';
|
||||
|
||||
// No directory for a group without control name
|
||||
if (!controlName || controlName.startsWith('check:') || controlName.startsWith('ext_link:')) {
|
||||
if (
|
||||
!controlName ||
|
||||
controlName.startsWith('check:') ||
|
||||
controlName.startsWith('ext_link:')
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -76,7 +88,10 @@ function prepareDirTree(control, dirTree) {
|
||||
return { dirTree };
|
||||
}
|
||||
|
||||
const bestPractice = require(path.join(__dirname, `../public/jsons/best-practices/${bestPracticeId}`));
|
||||
const bestPractice = require(path.join(
|
||||
__dirname,
|
||||
`../public/jsons/best-practices/${bestPracticeId}`
|
||||
));
|
||||
const controls = bestPractice.mockup.controls.control;
|
||||
|
||||
// Prepare the dir tree that we will be creating
|
||||
@ -129,11 +144,7 @@ function createDirTree(parentDir, dirTree, filePaths = {}) {
|
||||
// For each of the directory names, create a
|
||||
// directory inside the given directory
|
||||
childrenDirNames.forEach((dirName) => {
|
||||
createDirTree(
|
||||
path.join(parentDir, dirName),
|
||||
dirTree[dirName],
|
||||
filePaths
|
||||
);
|
||||
createDirTree(path.join(parentDir, dirName), dirTree[dirName], filePaths);
|
||||
});
|
||||
|
||||
return filePaths;
|
||||
@ -141,4 +152,4 @@ function createDirTree(parentDir, dirTree, filePaths = {}) {
|
||||
|
||||
// Create directories and get back the paths for created directories
|
||||
createDirTree(bestPracticeContentDirPath, dirTree);
|
||||
console.log('Created best practice content directory structure');
|
||||
console.log('Created best practice content directory structure');
|
||||
|
@ -1,4 +1,5 @@
|
||||
## CLI Tools
|
||||
|
||||
> A bunch of CLI scripts to make the development easier
|
||||
|
||||
## `roadmap-links.cjs`
|
||||
@ -34,5 +35,3 @@ For the content skeleton to be generated, we should have proper grouping, and th
|
||||
- Assign the name to the groups.
|
||||
- Group names have the format of `[sort]-[slug]` e.g. `100-internet`. Each group name should start with a number starting from 100 which helps with sorting of the directories and the files. Groups at the same level have the sequential sorting information.
|
||||
- Each groups children have a separate group and have the name similar to `[sort]-[parent-slug]:[child-slug]` where sort refers to the sorting of the `child-slug` and not the parent. Also parent-slug does not need to have the sorting information as a part of slug e.g. if parent was `100-internet` the children would be `100-internet:how-does-the-internet-work`, `101-internet:what-is-http`, `102-internet:browsers`.
|
||||
|
||||
|
||||
|
@ -95,7 +95,9 @@ async function run() {
|
||||
|
||||
const roadmapJson = require(path.join(ROADMAP_JSON_DIR, `${roadmapId}.json`));
|
||||
const groups = roadmapJson?.mockup?.controls?.control?.filter(
|
||||
(control) => control.typeID === '__group__' && !control.properties?.controlName?.startsWith('ext_link')
|
||||
(control) =>
|
||||
control.typeID === '__group__' &&
|
||||
!control.properties?.controlName?.startsWith('ext_link')
|
||||
);
|
||||
|
||||
if (!OPEN_AI_API_KEY) {
|
||||
@ -106,8 +108,9 @@ async function run() {
|
||||
|
||||
for (let group of groups) {
|
||||
const topicId = group?.properties?.controlName;
|
||||
const topicTitle = group?.children?.controls?.control?.find((control) => control?.typeID === 'Label')?.properties
|
||||
?.text;
|
||||
const topicTitle = group?.children?.controls?.control?.find(
|
||||
(control) => control?.typeID === 'Label'
|
||||
)?.properties?.text;
|
||||
const currTopicUrl = topicId.replace(/^\d+-/g, '/').replace(/:/g, '/');
|
||||
const contentFilePath = topicUrlToPathMapping[currTopicUrl];
|
||||
|
||||
|
@ -82,7 +82,10 @@ function prepareDirTree(control, dirTree, dirSortOrders) {
|
||||
return { dirTree, dirSortOrders };
|
||||
}
|
||||
|
||||
const roadmap = require(path.join(__dirname, `../public/jsons/roadmaps/${roadmapId}`));
|
||||
const roadmap = require(path.join(
|
||||
__dirname,
|
||||
`../public/jsons/roadmaps/${roadmapId}`
|
||||
));
|
||||
const controls = roadmap.mockup.controls.control;
|
||||
|
||||
// Prepare the dir tree that we will be creating and also calculate the sort orders
|
||||
|
@ -27,15 +27,24 @@ function populatePageAds({
|
||||
const isConfiguredActive = isActive.toLowerCase() === 'yes';
|
||||
|
||||
const currentDate = new Date();
|
||||
const isDateInRange = currentDate >= new Date(startDate) && currentDate <= new Date(endDate);
|
||||
const isDateInRange =
|
||||
currentDate >= new Date(startDate) && currentDate <= new Date(endDate);
|
||||
const shouldShowAd = isConfiguredActive && isDateInRange;
|
||||
|
||||
const urlPart = pageUrl.replace('https://roadmap.sh/', '').replace(/\?.+?$/, '');
|
||||
const urlPart = pageUrl
|
||||
.replace('https://roadmap.sh/', '')
|
||||
.replace(/\?.+?$/, '');
|
||||
|
||||
const parentDir = urlPart.startsWith('best-practices/') ? 'best-practices' : 'roadmaps';
|
||||
const parentDir = urlPart.startsWith('best-practices/')
|
||||
? 'best-practices'
|
||||
: 'roadmaps';
|
||||
const pageId = urlPart.replace(`${parentDir}/`, '');
|
||||
|
||||
const pageFilePath = path.join(__dirname, `../src/data/${parentDir}`, `${pageId}/${pageId}.md`);
|
||||
const pageFilePath = path.join(
|
||||
__dirname,
|
||||
`../src/data/${parentDir}`,
|
||||
`${pageId}/${pageId}.md`
|
||||
);
|
||||
|
||||
if (!fs.existsSync(pageFilePath)) {
|
||||
console.error(`Page file not found: ${pageFilePath}`);
|
||||
@ -48,7 +57,9 @@ function populatePageAds({
|
||||
const frontMatterRegex = /---\n([\s\S]*?)\n---/;
|
||||
|
||||
const existingFrontmatter = pageFileContent.match(frontMatterRegex)[1];
|
||||
const contentWithoutFrontmatter = pageFileContent.replace(frontMatterRegex, ``).trim();
|
||||
const contentWithoutFrontmatter = pageFileContent
|
||||
.replace(frontMatterRegex, ``)
|
||||
.trim();
|
||||
|
||||
let frontmatterObj = yaml.load(existingFrontmatter);
|
||||
delete frontmatterObj.sponsor;
|
||||
@ -77,7 +88,11 @@ function populatePageAds({
|
||||
frontmatterObj = Object.fromEntries(frontmatterValues);
|
||||
}
|
||||
|
||||
const newFrontmatter = yaml.dump(frontmatterObj, { lineWidth: 10000, forceQuotes: true, quotingType: '"' });
|
||||
const newFrontmatter = yaml.dump(frontmatterObj, {
|
||||
lineWidth: 10000,
|
||||
forceQuotes: true,
|
||||
quotingType: '"',
|
||||
});
|
||||
const newContent = `---\n${newFrontmatter}---\n\n${contentWithoutFrontmatter}`;
|
||||
|
||||
fs.writeFileSync(pageFilePath, newContent, 'utf8');
|
||||
|
@ -14,21 +14,21 @@ appearance, race, religion, or sexual identity and orientation.
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
- Using welcoming and inclusive language
|
||||
- Being respectful of differing viewpoints and experiences
|
||||
- Gracefully accepting constructive criticism
|
||||
- Focusing on what is best for the community
|
||||
- Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
- The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
- Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
@ -8,6 +8,7 @@
|
||||
"start": "astro dev",
|
||||
"build": "astro build",
|
||||
"preview": "astro preview",
|
||||
"format": "prettier --write .",
|
||||
"astro": "astro",
|
||||
"deploy": "NODE_DEBUG=gh-pages gh-pages -d dist -t",
|
||||
"compress:jsons": "node bin/compress-jsons.cjs",
|
||||
|
@ -100,7 +100,7 @@ const config: PlaywrightTestConfig = {
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: 'npm run dev',
|
||||
url: "http://localhost:3000",
|
||||
url: 'http://localhost:3000',
|
||||
reuseExistingServer: !process.env.CI,
|
||||
},
|
||||
};
|
||||
|
4748
pnpm-lock.yaml
4748
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
14
sitemap.mjs
14
sitemap.mjs
@ -27,8 +27,13 @@ export async function serializeSitemap(item) {
|
||||
'https://roadmap.sh/best-practices',
|
||||
'https://roadmap.sh/guides',
|
||||
'https://roadmap.sh/videos',
|
||||
...(await getRoadmapIds()).flatMap((id) => [`https://roadmap.sh/${id}`, `https://roadmap.sh/${id}/topics`]),
|
||||
...(await getBestPracticesIds()).map((id) => `https://roadmap.sh/best-practices/${id}`),
|
||||
...(await getRoadmapIds()).flatMap((id) => [
|
||||
`https://roadmap.sh/${id}`,
|
||||
`https://roadmap.sh/${id}/topics`,
|
||||
]),
|
||||
...(await getBestPracticesIds()).map(
|
||||
(id) => `https://roadmap.sh/best-practices/${id}`
|
||||
),
|
||||
];
|
||||
|
||||
// Roadmaps and other high priority pages
|
||||
@ -44,7 +49,10 @@ export async function serializeSitemap(item) {
|
||||
}
|
||||
|
||||
// Guide and video pages
|
||||
if (item.url.startsWith('https://roadmap.sh/guides') || item.url.startsWith('https://roadmap.sh/videos')) {
|
||||
if (
|
||||
item.url.startsWith('https://roadmap.sh/guides') ||
|
||||
item.url.startsWith('https://roadmap.sh/videos')
|
||||
) {
|
||||
return {
|
||||
...item,
|
||||
// @ts-ignore
|
||||
|
@ -15,9 +15,12 @@ export class Topic {
|
||||
this.activeTopicId = null;
|
||||
|
||||
this.handleRoadmapTopicClick = this.handleRoadmapTopicClick.bind(this);
|
||||
this.handleBestPracticeTopicClick = this.handleBestPracticeTopicClick.bind(this);
|
||||
this.handleBestPracticeTopicToggle = this.handleBestPracticeTopicToggle.bind(this);
|
||||
this.handleBestPracticeTopicPending = this.handleBestPracticeTopicPending.bind(this);
|
||||
this.handleBestPracticeTopicClick =
|
||||
this.handleBestPracticeTopicClick.bind(this);
|
||||
this.handleBestPracticeTopicToggle =
|
||||
this.handleBestPracticeTopicToggle.bind(this);
|
||||
this.handleBestPracticeTopicPending =
|
||||
this.handleBestPracticeTopicPending.bind(this);
|
||||
|
||||
this.close = this.close.bind(this);
|
||||
this.resetDOM = this.resetDOM.bind(this);
|
||||
@ -178,7 +181,10 @@ export class Topic {
|
||||
|
||||
this.resetDOM();
|
||||
|
||||
const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll(':', '/')}`;
|
||||
const topicUrl = `/best-practices/${bestPracticeId}/${topicId.replaceAll(
|
||||
':',
|
||||
'/'
|
||||
)}`;
|
||||
|
||||
this.renderTopicFromUrl(topicUrl).then(() => null);
|
||||
}
|
||||
@ -210,24 +216,30 @@ export class Topic {
|
||||
const matchingElements = [];
|
||||
|
||||
// Elements having sort order in the beginning of the group id
|
||||
document.querySelectorAll(`[data-group-id$="-${topicId}"]`).forEach((element) => {
|
||||
const foundGroupId = element?.dataset?.groupId || '';
|
||||
const validGroupRegex = new RegExp(`^\\d+-${topicId}$`);
|
||||
document
|
||||
.querySelectorAll(`[data-group-id$="-${topicId}"]`)
|
||||
.forEach((element) => {
|
||||
const foundGroupId = element?.dataset?.groupId || '';
|
||||
const validGroupRegex = new RegExp(`^\\d+-${topicId}$`);
|
||||
|
||||
if (validGroupRegex.test(foundGroupId)) {
|
||||
matchingElements.push(element);
|
||||
}
|
||||
});
|
||||
if (validGroupRegex.test(foundGroupId)) {
|
||||
matchingElements.push(element);
|
||||
}
|
||||
});
|
||||
|
||||
// Elements with exact match of the topic id
|
||||
document.querySelectorAll(`[data-group-id="${topicId}"]`).forEach((element) => {
|
||||
matchingElements.push(element);
|
||||
});
|
||||
document
|
||||
.querySelectorAll(`[data-group-id="${topicId}"]`)
|
||||
.forEach((element) => {
|
||||
matchingElements.push(element);
|
||||
});
|
||||
|
||||
// Matching "check:XXXX" box of the topic
|
||||
document.querySelectorAll(`[data-group-id="check:${topicId}"]`).forEach((element) => {
|
||||
matchingElements.push(element);
|
||||
});
|
||||
document
|
||||
.querySelectorAll(`[data-group-id="check:${topicId}"]`)
|
||||
.forEach((element) => {
|
||||
matchingElements.push(element);
|
||||
});
|
||||
|
||||
return matchingElements;
|
||||
}
|
||||
@ -258,29 +270,44 @@ export class Topic {
|
||||
return;
|
||||
}
|
||||
|
||||
const isClickedDone = e.target.id === this.markTopicDoneId || e.target.closest(`#${this.markTopicDoneId}`);
|
||||
const isClickedDone =
|
||||
e.target.id === this.markTopicDoneId ||
|
||||
e.target.closest(`#${this.markTopicDoneId}`);
|
||||
if (isClickedDone) {
|
||||
this.markAsDone(this.activeTopicId);
|
||||
this.close();
|
||||
}
|
||||
|
||||
const isClickedPending = e.target.id === this.markTopicPendingId || e.target.closest(`#${this.markTopicPendingId}`);
|
||||
const isClickedPending =
|
||||
e.target.id === this.markTopicPendingId ||
|
||||
e.target.closest(`#${this.markTopicPendingId}`);
|
||||
if (isClickedPending) {
|
||||
this.markAsPending(this.activeTopicId);
|
||||
this.close();
|
||||
}
|
||||
|
||||
const isClickedClose = e.target.id === this.closeTopicId || e.target.closest(`#${this.closeTopicId}`);
|
||||
const isClickedClose =
|
||||
e.target.id === this.closeTopicId ||
|
||||
e.target.closest(`#${this.closeTopicId}`);
|
||||
if (isClickedClose) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
init() {
|
||||
window.addEventListener('best-practice.topic.click', this.handleBestPracticeTopicClick);
|
||||
window.addEventListener('best-practice.topic.toggle', this.handleBestPracticeTopicToggle);
|
||||
window.addEventListener(
|
||||
'best-practice.topic.click',
|
||||
this.handleBestPracticeTopicClick
|
||||
);
|
||||
window.addEventListener(
|
||||
'best-practice.topic.toggle',
|
||||
this.handleBestPracticeTopicToggle
|
||||
);
|
||||
|
||||
window.addEventListener('roadmap.topic.click', this.handleRoadmapTopicClick);
|
||||
window.addEventListener(
|
||||
'roadmap.topic.click',
|
||||
this.handleRoadmapTopicClick
|
||||
);
|
||||
window.addEventListener('click', this.handleOverlayClick);
|
||||
window.addEventListener('contextmenu', this.rightClickListener);
|
||||
|
||||
|
@ -1,37 +1,36 @@
|
||||
---
|
||||
jsonUrl: "/jsons/best-practices/api-security.json"
|
||||
pdfUrl: "/pdfs/best-practices/api-security.pdf"
|
||||
jsonUrl: '/jsons/best-practices/api-security.json'
|
||||
pdfUrl: '/pdfs/best-practices/api-security.pdf'
|
||||
order: 2
|
||||
briefTitle: "API Security"
|
||||
briefDescription: "API Security Best Practices"
|
||||
briefTitle: 'API Security'
|
||||
briefDescription: 'API Security Best Practices'
|
||||
isNew: true
|
||||
isUpcoming: false
|
||||
title: "API Security Best Practices"
|
||||
description: "Detailed list of best practices to make your APIs secure"
|
||||
title: 'API Security Best Practices'
|
||||
description: 'Detailed list of best practices to make your APIs secure'
|
||||
dimensions:
|
||||
width: 968
|
||||
height: 1543.39
|
||||
sponsor:
|
||||
url: "https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account"
|
||||
title: "Featured Product"
|
||||
imageUrl: "https://i.imgur.com/e5fdI0q.png"
|
||||
description: "Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!"
|
||||
url: 'https://www.getambassador.io/products/edge-stack-api-gateway?utm_source=roadmap-sh&utm_medium=edge-stack-page&utm_campaign=new-account'
|
||||
title: 'Featured Product'
|
||||
imageUrl: 'https://i.imgur.com/e5fdI0q.png'
|
||||
description: 'Get your Kubernetes API Gateway up and running in 5 minutes with Ambassador Edge Stack!'
|
||||
event:
|
||||
category: "SponsorClick"
|
||||
action: "Ambassador Redirect"
|
||||
label: "API Security / Ambassador Link"
|
||||
category: 'SponsorClick'
|
||||
action: 'Ambassador Redirect'
|
||||
label: 'API Security / Ambassador Link'
|
||||
schema:
|
||||
headline: "API Security Best Practices"
|
||||
description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice."
|
||||
imageUrl: "https://roadmap.sh/best-practices/api-security.png"
|
||||
datePublished: "2023-02-21"
|
||||
dateModified: "2023-02-21"
|
||||
headline: 'API Security Best Practices'
|
||||
description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.'
|
||||
imageUrl: 'https://roadmap.sh/best-practices/api-security.png'
|
||||
datePublished: '2023-02-21'
|
||||
dateModified: '2023-02-21'
|
||||
seo:
|
||||
title: "API Security Best Practices"
|
||||
description: "Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice."
|
||||
title: 'API Security Best Practices'
|
||||
description: 'Detailed list of best practices to make your APIs secure. Each best practice carries further details and how to implement that best practice.'
|
||||
keywords:
|
||||
- "API Security"
|
||||
- "API Security Best Practices"
|
||||
- "API Security Checklist"
|
||||
- 'API Security'
|
||||
- 'API Security Best Practices'
|
||||
- 'API Security Checklist'
|
||||
---
|
||||
|
||||
|
@ -12,4 +12,4 @@ An API gateway can make your APIs more secure by providing a centralized point o
|
||||
|
||||
- Logging and monitoring: An API gateway can provide centralized logging and monitoring of API traffic, helping to identify and respond to security threats and other issues.
|
||||
|
||||
- Integration with security tools: An API gateway can be integrated with security tools such as WAFs, SIEMs, and other security tools to provide additional layers of protection.
|
||||
- Integration with security tools: An API gateway can be integrated with security tools such as WAFs, SIEMs, and other security tools to provide additional layers of protection.
|
||||
|
@ -12,4 +12,4 @@ Here are some examples of established authentication mechanisms that you can use
|
||||
|
||||
- Password hashing algorithms: Password hashing algorithms like bcrypt and scrypt are widely used to securely store and protect user passwords. These algorithms ensure that even if an attacker gains access to the password database, they will not be able to easily recover the passwords.
|
||||
|
||||
- Two-factor authentication (2FA): 2FA is an authentication mechanism that requires users to provide two forms of identification to access their accounts. This typically involves something the user knows (like a password) and something the user has (like a mobile device or security key). Many services and applications now offer 2FA as an additional security measure.
|
||||
- Two-factor authentication (2FA): 2FA is an authentication mechanism that requires users to provide two forms of identification to access their accounts. This typically involves something the user knows (like a password) and something the user has (like a mobile device or security key). Many services and applications now offer 2FA as an additional security measure.
|
||||
|
@ -6,4 +6,4 @@ Sending tokens in the query or body parameters is generally not recommended beca
|
||||
|
||||
Additionally, sending tokens in query or body parameters can make them more vulnerable to cross-site request forgery (CSRF) attacks. In a CSRF attack, an attacker can trick a user into submitting a request that includes their authentication token, which the attacker can then use to impersonate the user and gain access to their account.
|
||||
|
||||
By contrast, using the `Authorization` header to send tokens helps to ensure that the tokens are not logged or cached by intermediary systems, and it can also help to protect against CSRF attacks by allowing the server to validate the token before processing the request.
|
||||
By contrast, using the `Authorization` header to send tokens helps to ensure that the tokens are not logged or cached by intermediary systems, and it can also help to protect against CSRF attacks by allowing the server to validate the token before processing the request.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Avoid HTTP blocking if you are using huge amount of data by moving the HTTP heavy operations to background jobs or asynchronous tasks.
|
||||
|
||||
HTTP blocking is a common issue in web applications. It occurs when the application is unable to process incoming HTTP requests due to a large number of requests or a large amount of data. This can lead to the application becoming unresponsive and the server crashing. This can be prevented by moving HTTP heavy operations to background jobs or asynchronous tasks. You can use a message queue to queue the requests and process them in the background. This will allow the application to continue processing other requests while the heavy operations are being processed in the background.
|
||||
HTTP blocking is a common issue in web applications. It occurs when the application is unable to process incoming HTTP requests due to a large number of requests or a large amount of data. This can lead to the application becoming unresponsive and the server crashing. This can be prevented by moving HTTP heavy operations to background jobs or asynchronous tasks. You can use a message queue to queue the requests and process them in the background. This will allow the application to continue processing other requests while the heavy operations are being processed in the background.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Ensure that you aren't logging any sensitive data.
|
||||
|
||||
Make sure that you are not logging any sensitive data such as passwords, credit card numbers, or personal information. This is because logging sensitive data can expose it to attackers, allowing them to gain unauthorized access to your system or data. Additionally, logging sensitive data can violate data privacy laws and regulations, exposing you to legal liability.
|
||||
Make sure that you are not logging any sensitive data such as passwords, credit card numbers, or personal information. This is because logging sensitive data can expose it to attackers, allowing them to gain unauthorized access to your system or data. Additionally, logging sensitive data can violate data privacy laws and regulations, exposing you to legal liability.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Avoid user’s personal ID in the resource URLs e.g. users/242/orders
|
||||
|
||||
User's own resource ID should be avoided. Use `/me/orders` instead of `/user/654321/orders`. This will help avoid the risk of exposing the user’s personal ID that can be used for further attacks.
|
||||
User's own resource ID should be avoided. Use `/me/orders` instead of `/user/654321/orders`. This will help avoid the risk of exposing the user’s personal ID that can be used for further attacks.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Only return the data that is needed for the client to function.
|
||||
|
||||
Returning only the data that is needed for the client to function is an important best practice for API security. This is because limiting the amount of data that is returned reduces the amount of sensitive information that is exposed. By only returning the necessary data, you can help prevent security vulnerabilities such as data leakage, injection attacks, and other types of attacks that rely on exposing too much information. Additionally, reducing the amount of data returned can improve the performance of your API by reducing the amount of data that needs to be processed and transmitted.
|
||||
Returning only the data that is needed for the client to function is an important best practice for API security. This is because limiting the amount of data that is returned reduces the amount of sensitive information that is exposed. By only returning the necessary data, you can help prevent security vulnerabilities such as data leakage, injection attacks, and other types of attacks that rely on exposing too much information. Additionally, reducing the amount of data returned can improve the performance of your API by reducing the amount of data that needs to be processed and transmitted.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use CDN for file uploads
|
||||
|
||||
Using a Content Delivery Network (CDN) for file uploads can make an API more secure by offloading the file upload traffic from the API server and reducing the risk of DDoS attacks.
|
||||
Using a Content Delivery Network (CDN) for file uploads can make an API more secure by offloading the file upload traffic from the API server and reducing the risk of DDoS attacks.
|
||||
|
@ -10,4 +10,4 @@ Using centralized logins for all services and components is important for severa
|
||||
|
||||
- Centralized logins make it easier to enforce security policies across different services and components, ensuring that only authorized users can access sensitive data or perform certain actions.
|
||||
|
||||
To use centralized logins, you need to set up a single sign-on (SSO) system that enables users to authenticate once and then access multiple services without having to provide credentials again. This can be done using protocols like OAuth or SAML, which enable secure authentication and authorization across different applications and services. Once set up, you can use centralized logging tools like ELK stack, Splunk, or Graylog to collect logs from different services and components and analyze them in one place. This enables you to quickly identify and respond to security threats or anomalies.
|
||||
To use centralized logins, you need to set up a single sign-on (SSO) system that enables users to authenticate once and then access multiple services without having to provide credentials again. This can be done using protocols like OAuth or SAML, which enable secure authentication and authorization across different applications and services. Once set up, you can use centralized logging tools like ELK stack, Splunk, or Graylog to collect logs from different services and components and analyze them in one place. This enables you to quickly identify and respond to security threats or anomalies.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
Vulnerabilities in third-party libraries and components can be exploited by attackers to gain access to your system or data. These vulnerabilities can be introduced through outdated or insecure dependencies that have not been updated with the latest security patches.
|
||||
|
||||
By regularly checking for vulnerabilities and keeping your dependencies up to date, you can ensure that your API is not susceptible to known security risks. This can be done by using automated tools or services that scan your codebase and provide reports on any vulnerabilities found in your dependencies. By addressing these vulnerabilities promptly, you can reduce the risk of your API being compromised by attackers.
|
||||
By regularly checking for vulnerabilities and keeping your dependencies up to date, you can ensure that your API is not susceptible to known security risks. This can be done by using automated tools or services that scan your codebase and provide reports on any vulnerabilities found in your dependencies. By addressing these vulnerabilities promptly, you can reduce the risk of your API being compromised by attackers.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use a code review process and disregard self-approval.
|
||||
|
||||
Having a good code review process allows for additional sets of eyes to review the code and identify potential security issues or vulnerabilities. A code review process involves other team members reviewing the code to ensure it follows best practices and is secure. Disregarding self-approval means that the developer who wrote the code should not be the only one responsible for approving it for release. This helps to catch potential mistakes or oversights before the code is deployed, reducing the risk of security breaches or other issues.
|
||||
Having a good code review process allows for additional sets of eyes to review the code and identify potential security issues or vulnerabilities. A code review process involves other team members reviewing the code to ensure it follows best practices and is secure. Disregarding self-approval means that the developer who wrote the code should not be the only one responsible for approving it for release. This helps to catch potential mistakes or oversights before the code is deployed, reducing the risk of security breaches or other issues.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Send `Content-Security-Policy: default-src 'none'` header.
|
||||
|
||||
Sending the `Content-Security-Policy: default-src 'none'` header is a security best practice that helps prevent cross-site scripting (XSS) attacks. This header tells the browser to not allow any resources to be loaded from external sources, such as scripts, stylesheets, or images. It only allows resources that are explicitly whitelisted in the CSP header, such as scripts or stylesheets hosted on your own domain. This can help prevent malicious actors from injecting code into your web pages via XSS attacks, as the browser will not execute any scripts or load any resources that are not explicitly allowed by the CSP policy.
|
||||
Sending the `Content-Security-Policy: default-src 'none'` header is a security best practice that helps prevent cross-site scripting (XSS) attacks. This header tells the browser to not allow any resources to be loaded from external sources, such as scripts, stylesheets, or images. It only allows resources that are explicitly whitelisted in the CSP header, such as scripts or stylesheets hosted on your own domain. This can help prevent malicious actors from injecting code into your web pages via XSS attacks, as the browser will not execute any scripts or load any resources that are not explicitly allowed by the CSP policy.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Make sure to turn the debug mode off in production
|
||||
|
||||
Debug mode is a feature that is used to help developers debug their code. It is not meant to be used in production. It can expose sensitive information about the application and the server it is running on. Make sure to turn debug mode off in production.
|
||||
Debug mode is a feature that is used to help developers debug their code. It is not meant to be used in production. It can expose sensitive information about the application and the server it is running on. Make sure to turn debug mode off in production.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
Directory listings are a feature of web servers that allow users to view the contents of a directory on a server. By default, web servers often have directory listings enabled, which means that anyone who has access to the server can see all the files and directories in a given folder.
|
||||
|
||||
Turning off directory listings is important for API security because it prevents attackers from gaining access to sensitive files and directories on the server. If directory listings are enabled and an attacker gains access to the server, they can easily view and download any files that are not properly protected. By disabling directory listings, you can ensure that only authorized users can access the files and directories on the server.
|
||||
Turning off directory listings is important for API security because it prevents attackers from gaining access to sensitive files and directories on the server. If directory listings are enabled and an attacker gains access to the server, they can easily view and download any files that are not properly protected. By disabling directory listings, you can ensure that only authorized users can access the files and directories on the server.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Disable entity expansion if using XML, YML or any other language
|
||||
|
||||
Disabling entity expansion is important when using XML, YAML, or any other language that allows entities because it helps prevent XXE (XML External Entity) or YAML tag injection attacks. In these attacks, attacker normally injects some sort of custom code in the input to perform attacks against the application.. By disabling entity expansion, the input cannot be manipulated in this way, reducing the risk of such attacks.
|
||||
Disabling entity expansion is important when using XML, YAML, or any other language that allows entities because it helps prevent XXE (XML External Entity) or YAML tag injection attacks. In these attacks, attacker normally injects some sort of custom code in the input to perform attacks against the application.. By disabling entity expansion, the input cannot be manipulated in this way, reducing the risk of such attacks.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
If the XML parser is vulnerable to XXE attacks, the attacker can use this vulnerability to read files on the server, perform SSRF attacks, and more. This can lead to the disclosure of sensitive information, denial of service, and other attacks.
|
||||
|
||||
XXE (XML External Entity) attack is a type of attack that targets applications that parse XML input from untrusted sources. In this attack, an attacker injects a malicious XML payload. This payload can contain external entities that the attacker can use to retrieve sensitive data, execute remote code, or launch denial of service attacks. XXE attacks can be prevented by disabling external entity processing or by validating and sanitizing the XML input before parsing it.
|
||||
XXE (XML External Entity) attack is a type of attack that targets applications that parse XML input from untrusted sources. In this attack, an attacker injects a malicious XML payload. This payload can contain external entities that the attacker can use to retrieve sensitive data, execute remote code, or launch denial of service attacks. XXE attacks can be prevented by disabling external entity processing or by validating and sanitizing the XML input before parsing it.
|
||||
|
@ -1,6 +1,6 @@
|
||||
# Endpoint Authentication
|
||||
|
||||
> Check if all the protected endpoints are behind authentication
|
||||
to avoid broken authentication process
|
||||
> to avoid broken authentication process
|
||||
|
||||
By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected.
|
||||
By identifying and fixing broken authentication workflows, the API can prevent attacks such as brute force attacks, credential stuffing, session hijacking, and other authentication-related attacks. This can help ensure that the system is secure and that sensitive data is protected.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Always force the `Content-Type` header to be set to relevant MIME type.
|
||||
|
||||
Forcing the content-type for API security is important because it ensures that the client and server are communicating in a mutually agreed-upon format for the data being transmitted. This can prevent attacks such as content spoofing or injection, where an attacker tries to trick the server into processing malicious content by pretending that it is of a different content type. By forcing the content-type to a specific format, the server can validate that the data it is receiving is legitimate and safe to process. Additionally, forcing the content-type can help prevent certain types of parsing errors that could be exploited by attackers.
|
||||
Forcing the content-type for API security is important because it ensures that the client and server are communicating in a mutually agreed-upon format for the data being transmitted. This can prevent attacks such as content spoofing or injection, where an attacker tries to trick the server into processing malicious content by pretending that it is of a different content type. By forcing the content-type to a specific format, the server can validate that the data it is receiving is legitimate and safe to process. Additionally, forcing the content-type can help prevent certain types of parsing errors that could be exploited by attackers.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> You should have a good JWT secret to protect against token tempering as well as avoiding brute force attacks.
|
||||
|
||||
A strong secret key should be randomly generated, long, and complex, and should be stored securely and rotated periodically.
|
||||
A strong secret key should be randomly generated, long, and complex, and should be stored securely and rotated periodically.
|
||||
|
@ -6,4 +6,4 @@ SSL strip is a type of attack where an attacker intercepts traffic between a cli
|
||||
|
||||
In an SSL strip attack, the attacker sets up a man-in-the-middle (MITM) position between the client and the server. When the client initiates a connection with the server, the attacker intercepts the SSL/TLS traffic and removes or replaces the HTTPS links with HTTP links. This can trick the user into thinking they are using a secure connection when in fact, they are not. The attacker can then monitor and manipulate the data transmitted between the client and server.
|
||||
|
||||
HSTS header is a security header that instructs browsers to only access the site over HTTPS. This header is used to prevent SSL Strip attacks. It is a good practice to use HSTS header with SSL.
|
||||
HSTS header is a security header that instructs browsers to only access the site over HTTPS. This header is used to prevent SSL Strip attacks. It is a good practice to use HSTS header with SSL.
|
||||
|
@ -1 +1 @@
|
||||
#
|
||||
#
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Do not extract the algorithm from the header, use backend.
|
||||
|
||||
Extracting the algorithm from the header of a JWT token can pose a security risk, as an attacker could modify the algorithm and potentially gain unauthorized access. It is therefore recommended to verify the algorithm on the backend rather than extracting it from the header. This can help ensure that the algorithm used to sign and verify the token is secure and has not been tampered with.
|
||||
Extracting the algorithm from the header of a JWT token can pose a security risk, as an attacker could modify the algorithm and potentially gain unauthorized access. It is therefore recommended to verify the algorithm on the backend rather than extracting it from the header. This can help ensure that the algorithm used to sign and verify the token is secure and has not been tampered with.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Avoid storing sensitive data in JWT payload
|
||||
|
||||
Storing sensitive data in a JWT token payload can increase the risk of data breaches and other security incidents. If an attacker is able to obtain or tamper with the token, they could potentially access the sensitive data stored in the payload.
|
||||
Storing sensitive data in a JWT token payload can increase the risk of data breaches and other security incidents. If an attacker is able to obtain or tamper with the token, they could potentially access the sensitive data stored in the payload.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
Using agents to monitor all requests, responses, and errors allows for real-time monitoring and detection of any abnormal activity or potential attacks. These agents can be configured to track metrics such as response times, error rates, and usage patterns, which can help identify any anomalies that could be indicative of an attack. By monitoring all requests and responses, the agents can provide visibility into the behavior of the API, which can help identify any potential security vulnerabilities or weaknesses. Additionally, agents can be used to log and analyze all data flowing through the API, which can be useful for debugging and auditing purposes.
|
||||
|
||||
To use agents for monitoring, a dedicated monitoring solution can be deployed alongside the API. This solution can be configured to capture data from all requests and responses, and analyze the data for any anomalies or issues. Agents can be implemented using various monitoring tools and technologies such as agents for application performance monitoring (APM), log monitoring, and network monitoring. The agents should be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken.
|
||||
To use agents for monitoring, a dedicated monitoring solution can be deployed alongside the API. This solution can be configured to capture data from all requests and responses, and analyze the data for any anomalies or issues. Agents can be implemented using various monitoring tools and technologies such as agents for application performance monitoring (APM), log monitoring, and network monitoring. The agents should be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
You should send the `X-Content-Type-Options: nosniff` header to prevent [MIME type sniffing attacks](https://www.keycdn.com/support/what-is-mime-sniffing) on your web application. This header tells the browser not to override the response content type even if it's not the expected type. For example, if an attacker manages to upload an HTML file with a disguised extension like .jpg, the server may still send the correct content type header for the HTML file. However, some browsers may ignore this header and try to "sniff" the content type based on the actual contents of the file, leading to a potential cross-site scripting (XSS) attack.
|
||||
|
||||
By sending the `X-Content-Type-Options: nosniff` header, you tell the browser to always trust the provided content type and not try to sniff the content type. This helps to mitigate the risk of attackers exploiting content type mismatches to deliver malicious content to unsuspecting users.
|
||||
By sending the `X-Content-Type-Options: nosniff` header, you tell the browser to always trust the provided content type and not try to sniff the content type. This helps to mitigate the risk of attackers exploiting content type mismatches to deliver malicious content to unsuspecting users.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
A stack usually refers to the call stack or execution stack. It is a data structure used by the computer program to manage and keep track of the sequence of function calls, local variables, and other related data during the execution of the program.
|
||||
|
||||
A non-executable stack is a security mechanism that prevents malicious code from being executed by preventing the stack memory from being executed as code. This helps to prevent attacks such as buffer overflow attacks, where an attacker tries to overwrite the return address on the stack to redirect the program to execute malicious code. By using non-executable stacks, the program can keep the stack separate from executable code and help prevent these types of attacks.
|
||||
A non-executable stack is a security mechanism that prevents malicious code from being executed by preventing the stack memory from being executed as code. This helps to prevent attacks such as buffer overflow attacks, where an attacker tries to overwrite the return address on the stack to redirect the program to execute malicious code. By using non-executable stacks, the program can keep the stack separate from executable code and help prevent these types of attacks.
|
||||
|
@ -6,4 +6,4 @@ In OAuth, `redirect_uri` is a parameter that specifies the URI (Uniform Resource
|
||||
|
||||
It is important to validate the `redirect_uri` on the server-side to prevent attacks such as open redirection attacks. In an open redirection attack, an attacker can modify the `redirect_uri` parameter to redirect the user to a malicious website. By validating the `redirect_uri` on the server-side, you can ensure that the redirect URI is a valid and authorized URI for the client application.
|
||||
|
||||
Validating the `redirect_uri` on the server-side can also prevent other types of attacks such as phishing attacks or cross-site request forgery (CSRF) attacks. By verifying that the `redirect_uri` matches a predefined list of authorized URIs, you can ensure that the user is redirected to a trusted site after authentication is complete.
|
||||
Validating the `redirect_uri` on the server-side can also prevent other types of attacks such as phishing attacks or cross-site request forgery (CSRF) attacks. By verifying that the `redirect_uri` matches a predefined list of authorized URIs, you can ensure that the user is redirected to a trusted site after authentication is complete.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use server-side encryption instead of client-side encryption
|
||||
|
||||
Client-side encryption is not recommended because client side codebase can be easily reverse engineered which can lead to the exposure of encryption algorithms.
|
||||
Client-side encryption is not recommended because client side codebase can be easily reverse engineered which can lead to the exposure of encryption algorithms.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use UUIDs instead of auto-incrementing integers. UUIDs are globally unique, and are not sequential. They are also more difficult to guess than sequential integers.
|
||||
|
||||
Use of UUIDs over auto-incrementing IDs prevents attackers from guessing or iterating through resource IDs. UUIDs are randomly generated and contain 128 bits of entropy, making it practically impossible for attackers to guess them. In contrast, autoincrementing IDs can be easily predicted or iterated through, allowing attackers to access or manipulate resources they shouldn't have access to. Additionally, using UUIDs can help prevent information disclosure by hiding the order of resource creation or access.
|
||||
Use of UUIDs over auto-incrementing IDs prevents attackers from guessing or iterating through resource IDs. UUIDs are randomly generated and contain 128 bits of entropy, making it practically impossible for attackers to guess them. In contrast, autoincrementing IDs can be easily predicted or iterated through, allowing attackers to access or manipulate resources they shouldn't have access to. Additionally, using UUIDs can help prevent information disclosure by hiding the order of resource creation or access.
|
||||
|
@ -1,5 +1,3 @@
|
||||
# Proper HTTP Methods
|
||||
|
||||
Use the proper HTTP method according to the operation: `GET (read)`, `POST (create)`, `PUT/PATCH (replace/update)`, and `DELETE (to delete a record)`, and respond with `405 Method Not Allowed` if the requested method isn't appropriate for the requested resource.
|
||||
|
||||
|
||||
|
@ -1,10 +1,11 @@
|
||||
# Proper Response Code
|
||||
|
||||
> Return the proper status code according to the operation completed. e.g.
|
||||
>
|
||||
> - `200 OK`
|
||||
> - `400 Bad Request`
|
||||
> - `401 Unauthorized`
|
||||
> - `405 Method Not Allowed`
|
||||
> - ...etc.
|
||||
|
||||
Returning the proper status code according to the operation completed is important for API security because it allows the client to understand the outcome of their request and take appropriate actions. For example, if the server returns a 401 Unauthorized status code, the client knows that their authentication credentials are incorrect and can prompt the user to re-enter their login details. On the other hand, if the server returns a 200 OK status code even though the request failed, the client may not realize there was an issue and could potentially execute malicious actions or display incorrect data. Providing accurate status codes can help prevent security vulnerabilities and improve the overall reliability and usability of the API.
|
||||
Returning the proper status code according to the operation completed is important for API security because it allows the client to understand the outcome of their request and take appropriate actions. For example, if the server returns a 401 Unauthorized status code, the client knows that their authentication credentials are incorrect and can prompt the user to re-enter their login details. On the other hand, if the server returns a 200 OK status code even though the request failed, the client may not realize there was an issue and could potentially execute malicious actions or display incorrect data. Providing accurate status codes can help prevent security vulnerabilities and improve the overall reliability and usability of the API.
|
||||
|
@ -5,4 +5,4 @@ Have a look at the following resources for more information on API security:
|
||||
- [Collection of Resources for Building APIs](https://github.com/yosriady/awesome-api-devtools)
|
||||
- [CS253: Web Security](https://www.youtube.com/watch?v=5JJrJGZ_LjM&list=PL1y1iaEtjSYiiSGVlL1cHsXN_kvJOOhu-)
|
||||
- [Securing Web Applications](https://www.youtube.com/watch?v=WlmKwIe9z1Q)
|
||||
- [MIT 6.858: Computer Systems Security](https://www.youtube.com/watch?v=GqmQg-cszw4&list=PLUl4u3cNGP62K2DjQLRxDNRi0z2IRWnNh)
|
||||
- [MIT 6.858: Computer Systems Security](https://www.youtube.com/watch?v=GqmQg-cszw4&list=PLUl4u3cNGP62K2DjQLRxDNRi0z2IRWnNh)
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Remove fingerprinting headers (i.e. x-powered-by etc) from the HTTP request.
|
||||
|
||||
Fingerprinting headers can be used to identify the web server and its version. This information can be used by attackers to identify vulnerabilities in the web server and exploit them.
|
||||
Fingerprinting headers can be used to identify the web server and its version. This information can be used by attackers to identify vulnerabilities in the web server and exploit them.
|
||||
|
@ -3,4 +3,3 @@
|
||||
> Private APIs should only be accessible from safe listed IPs
|
||||
|
||||
Private APIs should only be accessible from safe-listed IPs to ensure that only authorized users or systems can access the API. By restricting access to specific IP addresses, you can prevent unauthorized access from external networks or malicious actors. This can help to protect sensitive data and prevent attacks such as DDoS or brute-force attacks. Additionally, restricting access to safe-listed IPs can help to ensure the reliability and performance of the API by preventing excessive traffic from unauthorized sources.
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Design a rollback solution for deployments.
|
||||
|
||||
Sometimes deploying a new version of the API can introduce unexpected bugs or issues that were not caught during testing. In such cases, rolling back to the previous version of the API can help to mitigate the impact of the issue and restore the service to a functional state. A well-designed rollback solution can help reduce downtime and minimize the impact on users.
|
||||
Sometimes deploying a new version of the API can introduce unexpected bugs or issues that were not caught during testing. In such cases, rolling back to the previous version of the API can help to mitigate the impact of the issue and restore the service to a functional state. A well-designed rollback solution can help reduce downtime and minimize the impact on users.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Continuously run security analysis on your code.
|
||||
|
||||
Continuous security analysis helps identify and address security vulnerabilities in the codebase before they can be exploited by attackers. It involves using automated tools and manual techniques to scan code for potential weaknesses, such as insecure coding practices, configuration errors, and outdated dependencies. By identifying and fixing vulnerabilities early in the development cycle, the risk of a security breach or data loss can be significantly reduced, improving the overall security posture of the system.
|
||||
Continuous security analysis helps identify and address security vulnerabilities in the codebase before they can be exploited by attackers. It involves using automated tools and manual techniques to scan code for potential weaknesses, such as insecure coding practices, configuration errors, and outdated dependencies. By identifying and fixing vulnerabilities early in the development cycle, the risk of a security breach or data loss can be significantly reduced, improving the overall security posture of the system.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
Encryption is a process of converting plain text data into a cipher text that can only be deciphered by someone who has the decryption key. This makes it difficult for attackers to access sensitive data, even if they are able to intercept it or gain unauthorized access to it.
|
||||
|
||||
To encrypt sensitive data, you can use encryption algorithms such as `AES` or `RSA`, along with a strong key management system to ensure that keys are securely stored and managed. Additionally, you can implement other security measures such as access controls, firewalls, and intrusion detection systems to further protect sensitive data.
|
||||
To encrypt sensitive data, you can use encryption algorithms such as `AES` or `RSA`, along with a strong key management system to ensure that keys are securely stored and managed. Additionally, you can implement other security measures such as access controls, firewalls, and intrusion detection systems to further protect sensitive data.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use alerts for SMS, Slack, Email, Kibana, Cloudwatch, etc.
|
||||
|
||||
Using alerts for various communication channels such as SMS, Slack, Email, Kibana, Cloudwatch, etc. can help you quickly respond to any issues or anomalies in your system. These alerts can be set up to notify you in real-time if a particular event or condition occurs, allowing you to take proactive measures to prevent downtime, data loss, or security breaches. Additionally, alerts can provide valuable insights into system performance and user behavior, allowing you to make informed decisions about your API's design and implementation.
|
||||
Using alerts for various communication channels such as SMS, Slack, Email, Kibana, Cloudwatch, etc. can help you quickly respond to any issues or anomalies in your system. These alerts can be set up to notify you in real-time if a particular event or condition occurs, allowing you to take proactive measures to prevent downtime, data loss, or security breaches. Additionally, alerts can provide valuable insights into system performance and user behavior, allowing you to make informed decisions about your API's design and implementation.
|
||||
|
@ -2,6 +2,6 @@
|
||||
|
||||
> Limit requests (throttling) to avoid DDoS / Brute Force attacks.
|
||||
|
||||
Limiting requests through throttling is important to prevent DDoS attacks and brute force attacks. DDoS attacks overwhelm the server with too many requests, while brute force attacks try to guess user credentials through multiple login attempts.
|
||||
Limiting requests through throttling is important to prevent DDoS attacks and brute force attacks. DDoS attacks overwhelm the server with too many requests, while brute force attacks try to guess user credentials through multiple login attempts.
|
||||
|
||||
Throttling limits the number of requests that can be sent within a certain time period, making it harder for attackers to carry out these types of attacks. This can protect the system from being overwhelmed and can prevent attackers from gaining unauthorized access.
|
||||
Throttling limits the number of requests that can be sent within a certain time period, making it harder for attackers to carry out these types of attacks. This can protect the system from being overwhelmed and can prevent attackers from gaining unauthorized access.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Token expiry should be set to a reasonable time to reduce the window of vulnerability, limit the impact of token theft, and improve overall security.
|
||||
|
||||
Setting a short token expiration time (TTL, RTTL) is important for security purposes, as it reduces the window of vulnerability, limits the impact of token theft, and improves overall security. However, the expiration time should be balanced with usability, as setting it too short may inconvenience users and reduce productivity.
|
||||
Setting a short token expiration time (TTL, RTTL) is important for security purposes, as it reduces the window of vulnerability, limits the impact of token theft, and improves overall security. However, the expiration time should be balanced with usability, as setting it too short may inconvenience users and reduce productivity.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Audit your design and implementation with unit/integration tests coverage.
|
||||
|
||||
Unit and integration testing can help identify vulnerabilities in the API code and design, such as input validation errors, authentication and authorization flaws, and other security-related issues. By performing comprehensive testing, developers can ensure that the API works as intended and that it is secure against common attacks such as injection attacks, cross-site scripting, and other exploits. Adequate testing can also help identify and resolve performance bottlenecks, improve scalability and reliability, and ensure the overall quality of the API.
|
||||
Unit and integration testing can help identify vulnerabilities in the API code and design, such as input validation errors, authentication and authorization flaws, and other security-related issues. By performing comprehensive testing, developers can ensure that the API works as intended and that it is secure against common attacks such as injection attacks, cross-site scripting, and other exploits. Adequate testing can also help identify and resolve performance bottlenecks, improve scalability and reliability, and ensure the overall quality of the API.
|
||||
|
@ -5,4 +5,3 @@
|
||||
Ensure that your API server uses HTTPS instead of HTTP. HTTPS is a secure protocol that encrypts data in transit, making it difficult for attackers to intercept and read sensitive information. To implement HTTPS, you need to obtain an SSL/TLS certificate and configure your server to use HTTPS.
|
||||
|
||||
HTTPS uses ciphers to encrypt data in transit. It is important to choose secure ciphers that are resistant to attacks and offer strong encryption. Some common secure ciphers include AES, ChaCha20, and ECDHE for key exchange. Make sure to disable weak and outdated ciphers, such as RC4 and TLS 1.0/1.1, which are vulnerable to attacks.
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use IDS and/or IPS systems to detect and block attacks.
|
||||
|
||||
Intrusion detection systems (IDS) and intrusion prevention systems (IPS) can be used to detect and block attacks. These systems can be configured to monitor all incoming and outgoing traffic, and detect any suspicious activity. If any suspicious activity is detected, the systems can be configured to block the traffic, preventing the attack from succeeding. IDS and IPS systems can be implemented using various tools and technologies such as network intrusion detection systems (NIDS), host-based intrusion detection systems (HIDS), and network intrusion prevention systems (NIPS). These systems can be deployed alongside the API, and configured to monitor all incoming and outgoing traffic. The systems can be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken.
|
||||
Intrusion detection systems (IDS) and intrusion prevention systems (IPS) can be used to detect and block attacks. These systems can be configured to monitor all incoming and outgoing traffic, and detect any suspicious activity. If any suspicious activity is detected, the systems can be configured to block the traffic, preventing the attack from succeeding. IDS and IPS systems can be implemented using various tools and technologies such as network intrusion detection systems (NIDS), host-based intrusion detection systems (HIDS), and network intrusion prevention systems (NIPS). These systems can be deployed alongside the API, and configured to monitor all incoming and outgoing traffic. The systems can be configured to provide real-time alerts to security teams if any suspicious activity is detected, allowing for immediate action to be taken.
|
||||
|
@ -14,4 +14,4 @@ There are several reasons why basic authentication should be avoided and replace
|
||||
|
||||
- No support for multi-factor authentication: Basic authentication does not support multi-factor authentication (MFA), which is a critical security feature that provides an additional layer of protection against unauthorized access.
|
||||
|
||||
In contrast, other authentication techniques such as OAuth, OpenID Connect, and SAML provide more secure and robust methods for authentication. These methods typically use encrypted protocols to protect the user's credentials, provide mechanisms for verifying the integrity of the data, and support MFA. As a result, they are much more secure and reliable than basic authentication and should be used whenever possible.
|
||||
In contrast, other authentication techniques such as OAuth, OpenID Connect, and SAML provide more secure and robust methods for authentication. These methods typically use encrypted protocols to protect the user's credentials, provide mechanisms for verifying the integrity of the data, and support MFA. As a result, they are much more secure and reliable than basic authentication and should be used whenever possible.
|
||||
|
@ -3,4 +3,3 @@
|
||||
> Validate `content-type` on request headers to prevent XSS attacks
|
||||
|
||||
Validating the `Content-Type` header on the request can help to make APIs more secure by ensuring that the request data is in the expected format and reducing the risk of attacks such as injection attacks or cross-site scripting (XSS).
|
||||
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Validate user input to avoid common vulnerabilities
|
||||
|
||||
User input is a common source of vulnerabilities in web applications. This is because user input is often not properly validated, sanitized, or escaped before being used in a web application. This can allow an attacker to manipulate the input and execute malicious code or cause the application to behave unexpectedly.
|
||||
User input is a common source of vulnerabilities in web applications. This is because user input is often not properly validated, sanitized, or escaped before being used in a web application. This can allow an attacker to manipulate the input and execute malicious code or cause the application to behave unexpectedly.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Send `X-Frame-Options: deny` header.
|
||||
|
||||
The `X-Frame-Options` header prevents the page from being displayed in an iframe, which is commonly used in clickjacking attacks. By setting the value of this header to `deny`, you are telling the browser not to display the page in any iframe. This helps prevent the page from being embedded within an attacker's website and reduces the risk of clickjacking attacks.
|
||||
The `X-Frame-Options` header prevents the page from being displayed in an iframe, which is commonly used in clickjacking attacks. By setting the value of this header to `deny`, you are telling the browser not to display the page in any iframe. This helps prevent the page from being embedded within an attacker's website and reduces the risk of clickjacking attacks.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Get your alerts to become notifications.
|
||||
|
||||
If you've set everyting up correctly, your health checks should automatically destroy bad instances and spawn new ones. There's usually no action to take when getting a CloudWatch alert, as everything should be automated. If you're getting alerts where manual intervention is required, do a post-mortem and figure out if there's a way you can automate the action in future. The last time I had an actionable alert from CloudWatch was about a year ago, and it's extremely awesome not to be woken up at 4am for ops alerts any more.
|
||||
If you've set everyting up correctly, your health checks should automatically destroy bad instances and spawn new ones. There's usually no action to take when getting a CloudWatch alert, as everything should be automated. If you're getting alerts where manual intervention is required, do a post-mortem and figure out if there's a way you can automate the action in future. The last time I had an actionable alert from CloudWatch was about a year ago, and it's extremely awesome not to be woken up at 4am for ops alerts any more.
|
||||
|
@ -1,3 +1,3 @@
|
||||
# App Changes for AWS
|
||||
|
||||
While a lot of applications can probably just be deployed to an EC2 instance and work well, if you're coming from a physical environment, you may need to re-architect your application in order to accomodate changes. Don't just think you can copy the files over and be done with it.
|
||||
While a lot of applications can probably just be deployed to an EC2 instance and work well, if you're coming from a physical environment, you may need to re-architect your application in order to accomodate changes. Don't just think you can copy the files over and be done with it.
|
||||
|
@ -1,3 +1,3 @@
|
||||
# Automate Everything
|
||||
|
||||
This is more of general operations advice than AWS specific, but everything needs to be automated. Recovery, deployment, failover, etc. Package and OS updates should be managed by something, whether it's just a bash script, or Chef/Puppet, etc. You shouldn't have to care about this stuff. As mentioned in a different tip, you should also make sure to disable SSH access, as this will pretty quickly highlight any part of your process that isn't automated. Remember the key phrase from the earlier tip, if you have to SSH into your servers, then your automation has failed.
|
||||
This is more of general operations advice than AWS specific, but everything needs to be automated. Recovery, deployment, failover, etc. Package and OS updates should be managed by something, whether it's just a bash script, or Chef/Puppet, etc. You shouldn't have to care about this stuff. As mentioned in a different tip, you should also make sure to disable SSH access, as this will pretty quickly highlight any part of your process that isn't automated. Remember the key phrase from the earlier tip, if you have to SSH into your servers, then your automation has failed.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Avoid filesystem mounts (FUSE, etc).
|
||||
|
||||
I've found them to be about as reliable as a large government department when used in critical applications. Use the SDK instead.
|
||||
I've found them to be about as reliable as a large government department when used in critical applications. Use the SDK instead.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Don't use multiple scaling triggers on the same group.
|
||||
|
||||
If you have multiple CloudWatch alarms which trigger scaling actions for the same auto-scaling group, it might not work as you initially expect it to. For example, let's say you add a trigger to scale up when CPU usage gets too high, or when the inbound network traffic gets high, and your scale down actions are the opposite. You might get an increase in CPU usage, but your inbound network is fine. So the high CPU trigger causes a scale-up action, but the low inbound traffic alarm immediately triggers a scale-down action. Depending on how you've set your cooldown period, this can cause quite a problem as they'll just fight against each other. If you want multiple triggers, you can use multiple auto-scaling groups.
|
||||
If you have multiple CloudWatch alarms which trigger scaling actions for the same auto-scaling group, it might not work as you initially expect it to. For example, let's say you add a trigger to scale up when CPU usage gets too high, or when the inbound network traffic gets high, and your scale down actions are the opposite. You might get an increase in CPU usage, but your inbound network is fine. So the high CPU trigger causes a scale-up action, but the low inbound traffic alarm immediately triggers a scale-down action. Depending on how you've set your cooldown period, this can cause quite a problem as they'll just fight against each other. If you want multiple triggers, you can use multiple auto-scaling groups.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Don't give servers static/elastic IPs.
|
||||
|
||||
For a typical web application, you should put things behind a load balancer, and balance them between AZs. There are a few cases where Elastic IPs will probably need to be used, but in order to make best use of auto-scaling you'll want to use a load balancer instad of giving every instance their own unique IP.
|
||||
For a typical web application, you should put things behind a load balancer, and balance them between AZs. There are a few cases where Elastic IPs will probably need to be used, but in order to make best use of auto-scaling you'll want to use a load balancer instad of giving every instance their own unique IP.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Make sure AWS is right for your workload.
|
||||
|
||||
You should make sure that using AWS is correct for your particular workload. If you have a steady load and 24/7 servers, it's possible there are cheaper providers you can use, or it might even be cheaper to use dedicated hardware of your own. One of the big benefits of AWS is the ability to scale up and down rapidly in response to load, but not everyone needs that feature. As when purchasing anything, you should shop around a bit first to make sure you're getting the best deal for what you need
|
||||
You should make sure that using AWS is correct for your particular workload. If you have a steady load and 24/7 servers, it's possible there are cheaper providers you can use, or it might even be cheaper to use dedicated hardware of your own. One of the big benefits of AWS is the ability to scale up and down rapidly in response to load, but not everyone needs that feature. As when purchasing anything, you should shop around a bit first to make sure you're getting the best deal for what you need
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Be aware of AWS service limits before you deploy.
|
||||
|
||||
Various service limits are enforced which aren't highlighted until you're actually trying to deploy your application and get the error notification. These limits can easily be increased by making a request to AWS support, however that can involve a significant turn around time (as low as a few minutes, up to a few days, based on past experience), during which you won't be able to finish deploying. A few days before deploying, you should consult the service limits page to see if you think you're going to exceed any of them, and make your support request ahead of time. You will need to make a separate request to each department where you need a limit increased. It's also worth pointing out that some limits are global, while others are per-region.
|
||||
Various service limits are enforced which aren't highlighted until you're actually trying to deploy your application and get the error notification. These limits can easily be increased by making a request to AWS support, however that can involve a significant turn around time (as low as a few minutes, up to a few days, based on past experience), during which you won't be able to finish deploying. A few days before deploying, you should consult the service limits page to see if you think you're going to exceed any of them, and make your support request ahead of time. You will need to make a separate request to each department where you need a limit increased. It's also worth pointing out that some limits are global, while others are per-region.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Set up granular billing alerts.
|
||||
|
||||
You should always have at least one billing alert set up, but that will only tell you on a monthly basis once you've exceeded your allowance. If you want to catch runaway billing early, you need a more fine grained approach. The way I do it is to set up an alert for my expected usage each week. So the first week's alert for say $1,000, the second for $2,000, third for $3,000, etc. If the week-2 alarm goes off before the 14th/15th of the month, then I know something is probably going wrong. For even more fine-grained control, you can set this up for each individual service, that way you instantly know which service is causing the problem. This could be useful if your usage on one service is quite steady month-to-month, but another is more erratic. Have the indidividual weekly alerts for the steady one, but just an overall one for the more erratic one. If everything is steady, then this is probably overkill, as looking at CloudWatch will quickly tell you which service is the one causing the problem.
|
||||
You should always have at least one billing alert set up, but that will only tell you on a monthly basis once you've exceeded your allowance. If you want to catch runaway billing early, you need a more fine grained approach. The way I do it is to set up an alert for my expected usage each week. So the first week's alert for say $1,000, the second for $2,000, third for $3,000, etc. If the week-2 alarm goes off before the 14th/15th of the month, then I know something is probably going wrong. For even more fine-grained control, you can set this up for each individual service, that way you instantly know which service is causing the problem. This could be useful if your usage on one service is quite steady month-to-month, but another is more erratic. Have the indidividual weekly alerts for the steady one, but just an overall one for the more erratic one. If everything is steady, then this is probably overkill, as looking at CloudWatch will quickly tell you which service is the one causing the problem.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use "-" instead of "." in bucket names for SSL.
|
||||
|
||||
If you ever want to use your bucket over SSL, using a "." will cause you to get certificate mismatch errors. You can't change bucket names once you've created them, so you'd have to copy everything to a new bucket.
|
||||
If you ever want to use your bucket over SSL, using a "." will cause you to get certificate mismatch errors. You can't change bucket names once you've created them, so you'd have to copy everything to a new bucket.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use CloudTrail to keep an audit log.
|
||||
|
||||
CloudTrail will log any action performed via the APIs or web console into an S3 bucket. Set up the bucket with versioning to be sure no one can modify your logs, and you then have a complete audit trail of all changes in your account. You hope that you will never need to use this, but it's well worth having for when you do.
|
||||
CloudTrail will log any action performed via the APIs or web console into an S3 bucket. Set up the bucket with versioning to be sure no one can modify your logs, and you then have a complete audit trail of all changes in your account. You hope that you will never need to use this, but it's well worth having for when you do.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use the CLI tools.
|
||||
|
||||
It can become extremely tedious to create alarms using the web console, especially if you're setting up a lot of similar alarms, as there's no ability to "clone" an existing alarm while making a minor change elsewhere. Scripting this using the CLI tools can save you lots of time.
|
||||
It can become extremely tedious to create alarms using the web console, especially if you're setting up a lot of similar alarms, as there's no ability to "clone" an existing alarm while making a minor change elsewhere. Scripting this using the CLI tools can save you lots of time.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use detailed monitoring.
|
||||
|
||||
It's ~$3.50 per instance/month, and well worth the extra cost for the extra detail. 1 minute granularity is much better than 5 minute. You can have cases where a problem is hidden in the 5 minute breakdown, but shows itself quite clearly in the 1 minute graphs. This may not be useful for everyone, but it's made investigating some issues much easier for me.
|
||||
It's ~$3.50 per instance/month, and well worth the extra cost for the extra detail. 1 minute granularity is much better than 5 minute. You can have cases where a problem is hidden in the 5 minute breakdown, but shows itself quite clearly in the 1 minute graphs. This may not be useful for everyone, but it's made investigating some issues much easier for me.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use the free metrics.
|
||||
|
||||
CloudWatch monitors all sorts of things for free (bandwidth, CPU usage, etc.), and you get up to 2 weeks of historical data. This saves you having to use your own tools to monitor you systems. If you need longer than 2 weeks, unfortunately you'll need to use a third-party or custom built monitoring solution.
|
||||
CloudWatch monitors all sorts of things for free (bandwidth, CPU usage, etc.), and you get up to 2 weeks of historical data. This saves you having to use your own tools to monitor you systems. If you need longer than 2 weeks, unfortunately you'll need to use a third-party or custom built monitoring solution.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Only use the availability zones (AZs) your ELB is configured for.
|
||||
|
||||
If you add your scaling group to multiple AZs, make sure your ELB is configured to use all of those AZs, otherwise your capacity will scale up, and the load balancer won't be able to see them.
|
||||
If you add your scaling group to multiple AZs, make sure your ELB is configured to use all of those AZs, otherwise your capacity will scale up, and the load balancer won't be able to see them.
|
||||
|
@ -4,4 +4,4 @@
|
||||
|
||||
This sounds crazy, I know, but port 22 should be disallowed for everyone in your security group. If there's one thing you take away from this post, this should be it: **If you have to SSH into your servers, then your automation has failed**. Disabling it at the firewall level (rather than on the servers themselves) will help the transition to this frame of thinking, as it will highlight any areas you need to automate, while still letting you easily re-instate access to solve immediate issues. It's incredibly freeing to know that you never need to SSH into an instance. This is both the most frightening and yet most useful thing I've learned.
|
||||
|
||||
Disabling inbound SSH has just been a way for me to stop myself cheating with automation (Oh, I'll just SSH in and fix this one thing). I can still re-enable it in the security group if I need to actively debug something on an instance, since sometimes there really is no other way to debug certain issues. It also depends on your application; If your application relies on you being able to push things to a server via SSH, then disabling it might be a bad idea. Blocking inbound SSH worked for me, and forced me to get my automation into a decent state, but it might not be for everyone.
|
||||
Disabling inbound SSH has just been a way for me to stop myself cheating with automation (Oh, I'll just SSH in and fix this one thing). I can still re-enable it in the security group if I need to actively debug something on an instance, since sometimes there really is no other way to debug certain issues. It also depends on your application; If your application relies on you being able to push things to a server via SSH, then disabling it might be a bad idea. Blocking inbound SSH worked for me, and forced me to get my automation into a decent state, but it might not be for everyone.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Use EC2 roles, do not give applications an IAM account.
|
||||
|
||||
If your application has AWS credentials baked into it, you're "doing it wrong". One of the reasons it's important to use the AWS SDK for your language is that you can really easily use EC2 IAM roles. The idea of a role is that you specify the permissions a certain role should get, then assign that role to an EC2 instance. Whenever you use the AWS SDK on that instance, you don't specify any credentials. Instead, the SDK will retrieve temporary credentials which have the permissions of the role you set up. This is all handled transparently as far as you're concerned. It's secure, and extremely useful.
|
||||
If your application has AWS credentials baked into it, you're "doing it wrong". One of the reasons it's important to use the AWS SDK for your language is that you can really easily use EC2 IAM roles. The idea of a role is that you specify the permissions a certain role should get, then assign that role to an EC2 instance. Whenever you use the AWS SDK on that instance, you don't specify any credentials. Instead, the SDK will retrieve temporary credentials which have the permissions of the role you set up. This is all handled transparently as far as you're concerned. It's secure, and extremely useful.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Set up event subscriptions for failover.
|
||||
|
||||
If you're using a Multi-AZ setup, this is one of those things you might not think about which ends up being incredibly useful when you do need it.
|
||||
If you're using a Multi-AZ setup, this is one of those things you might not think about which ends up being incredibly useful when you do need it.
|
||||
|
@ -2,4 +2,4 @@
|
||||
|
||||
> Assign permissions to groups, not users.
|
||||
|
||||
Managing users can be a pain, if you're using Active Directory, or some other external authentication mechanism which you've integrated with IAM, then this probably won't matter as much (or maybe it matters more). But I've found it much easier to manage permissions by assigning them only to groups, rather than to individual users. It's much easier to rein in permissions and get an overall view of the system than going through each individual user to see what permissions have been assigned.
|
||||
Managing users can be a pain, if you're using Active Directory, or some other external authentication mechanism which you've integrated with IAM, then this probably won't matter as much (or maybe it matters more). But I've found it much easier to manage permissions by assigning them only to groups, rather than to individual users. It's much easier to rein in permissions and get an overall view of the system than going through each individual user to see what permissions have been assigned.
|
||||
|
@ -1 +1 @@
|
||||
#
|
||||
#
|
||||
|
@ -2,4 +2,4 @@
|
||||